我有这个使用Tie::File perl脚本。
在Linux(Ubuntu)中,当我通过Bash调用脚本时,它可以正常工作,但是在Windows中,当我通过Powershell调用脚本时,它的行为exception(请查看下面的PS)。
代码 :
#!/usr/bin/perl -T use strict; use warnings; use Tie::File; use CommonStringTasks; if ( @ARGV != 4 ) { print "ERROR:Inadequate/Redundant arguments.n"; print "Usage: perl <pl_executable> <path/to/peer_main.java> <peer_main.java>n"; print " <score_file_index> <port_step_index>n"; print $ARGV[0],"n"; print $ARGV[1],"n"; print $ARGV[2],"n"; print $ARGV[3],"n"; exit 1; } my $PEER_DIR = $ARGV[0]; my $PEER_FILE = $ARGV[1]; my $PEER_PACKAGE = "src/planetlab/app"; my $PEER_PATH = "${PEER_DIR}/${PEER_PACKAGE}/${PEER_FILE}"; # Check if args are tainted ... # Check $PEER_PATH file permissions ... open(my $file,"+<","$PEER_PATH") or die("File ",$PEER_FILE," Could not be opened for editing:$!"); # Edit the file and change variables for debugging/deployment setup. # Number demanglers: # -flock -> arg2 -> 2 stands for FILE_EX # Options (critical!): # -Memory: Inhibit caching as this will allow record changes on the fly. tie my @fileLines,'Tie::File',$file,memory => 0 or die("File "," Could not be tied with Tie::File:$!"); flock $file,2; my $i = 0; my $scoreLine = "int FILE_INDEX = " . $score . ";"; my $portLine = "int SERVER_PORT = " . $PORT . ";"; my $originalscoreLine = "int FILE_INDEX ="; my $originalPortLine = "int SERVER_PORT ="; (tied @fileLines)->defer; while (my $line = <$file>) { if ( ($line =~ m/($scoreLine)/) && ($score+1 > 0) ) { print "Original line (score): ","n",$scoreLine,"n"; chomp $line; $line = substr($line,-($scoreDigits+1)); $line = $line . (++$score) . ";"; print "Editing line (score): ",$i,trimLeadspaces($fileLines[$i]),"n"; $fileLines[$i] = $line; print "Line replaced with:n",trimLeadspaces($line),"n"; next; } if ( ($line =~ m/($portLine)/) && ($PORT > 0) ) { print "Original line (port): ",$portLine,-($portDigits+1)); $line = $line . (++$PORT) . ";"; print "Editing line (port): ","n"; last; } # Restore original settings. if ( ($line =~ m/($originalscoreLine)/) && ($score < 0) ) { print "Restoring line (score) - FROM: ",$fileLines[$i],"n"; $fileLines[$i] = " private static final int FILE_INDEX = 0;"; print "Restoring line (score) - TO: ","n"; next; } if ( ($line =~ m/($originalPortLine)/) && ($PORT < 0) ) { print "Restoring line (port) - FROM: ","n"; $PORT = abs($PORT); $fileLines[$i] = " private static final int SERVER_PORT = " . $PORT . ";"; print "Restoring line (port) - TO: ","n"; last; } } continue { $i++; } (tied @fileLines)->flush; untie @fileLines; close $file;
两个操作系统中的perl版本都是5+(在带有CPAN模块的Windows Active-State Perl中)。
难道是我打开文件句柄的方式吗? 任何想法的人?
从HTML表格中提取数据
运行多个python的linux bash脚本
如何通过SFTP将数据传输到远程文件而不将数据存储在Linux Bash的本地文件中?
PS:第一个版本有一段while (<$file>) ,而不是$line我使用$_variables,但是当我这样做,我有一个行为,特定的行不会被编辑,而是文件会附加一个百个换行符,然后是(正确)编辑的行,等等。 我还有一个关于$fileLines[$i]被初始化的警告!很显然,Windows中的Tie::File结构有些问题,或者其他我不知道的东西。 这种变化也会发生同样的不稳定行为,而Linux(Ubuntu)的行为又如预期的那样。
Linux的Azure自定义脚本扩展
如何使用redirect和pipe道命令bash命令string?
快速recursionsearch并通过bash / sed / awk通过大量文件进行replace – 有可能吗?
使用bash下载需要authentication的页面
Linux的bash脚本:如何在列上search,但返回完整的行?
OP的问题是模糊的,缺乏投入和预期的产出。 因此,我只是简单地指出我的一些担忧:
首先,在同一个句柄上使用Tie::File和<$file>和flock似乎既矫枉过正又危险。 我会建议使用Tie::File进行迭代和编辑,比如:
#!/usr/bin/env perl use strict; use warnings; use Tie::File; tie my @lines,'filename'; foreach my $linenum ( 0..$#lines ) { if ($lines[$linenum] =~ /something/) { $lines[$linenum] = 'somethingelse'; } }
也许比编辑内联更好,因为Tie::File允许,将文件复制到备份,使用<$file>遍历行,然后用旧名写入新文件。
#!/usr/bin/env perl use strict; use warnings; use File::copy 'move'; my $infile = $ARGV[0]; move( $infile,"$infile.bak"); open my $inhandle,'<',"$infile.bak"; open my $outhandle,'>',$infile; while( my $line = <$inhandle> ) { if ($line =~ /something/) { $line = 'somethingelse'; } print $outhandle $line; }
其次, -Mmodulee标志简单地转换为use modulee; 在脚本的顶部。 因此-MCPAN use CPAN; ,但是加载CPAN模块对脚本没有任何作用。 CPAN.pm给脚本提供了安装模块的能力。
第三,如果您输入和输入示例,预期的输出以及清晰的脚本,清楚地显示此操作的执行方式,但仍然会以与实际脚本相同的方式失败,我们将能够更好地提供帮助。
我发现了我的问题的来源。
原因是记录分隔符!
Tie::File Windows中预期的Tie::File a /r/n记录分隔符,所以它只需一次读取整个文件。 我的文件是用UTF-8编写的 ,有Unix的结尾 。
这就是为什么当我遍历$fileLines并访问超过0的任何索引时,我从perl得到了一个警告,说该字符串没有被初始化。 修复了这个问题,现在我准备好了! :d
PS:Joel Berger先生我将你的回答标为有效/恰当,因为你确实试图帮助我,而且我遵循了你对文件句柄的第一个建议:)。 谢谢大家帮助我xD xD xD
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。