以下Perl单行程按预期工作;它剥离我的前导和尾随退格的文件,并用一个标签替换中间空格:
$ perl -pi -le 's/^\s+//; s/\s+$//; s#\s+#\t#g;' file
令我困惑的是为什么我无法通过我的Perl代码中的system
调用来实现此目的:
system "perl -pi -le 's/^\s+//; s/\s+\$//; s#\s+#\t#g;' file"; # '$' backslashed
这里有什么问题?
答案 0 :(得分:3)
没有必要为-i启动另一个进程,但通常你应该本地化一些全局变量:
sub do_stuff {
my $file = shift;
local ($_, $., $ARGV, *ARGV);
local ( $^I, @ARGV ) = ( '.bak', $file );
while ( <> ) {
s/..../..../;
print;
}
}
答案 1 :(得分:2)
say "perl -pi -le 's/^\s+//; s/\s+\$//; s#\s+#\t#g;' file";
产生
Unrecognized escape \s passed through at -e line 1.
Unrecognized escape \s passed through at -e line 1.
Unrecognized escape \s passed through at -e line 1.
perl -pi -le 's/^s+//; s/s+$//; s#s+# #g;' file
你想要
system("perl -pi -le 's/^\\s+//; s/\\s+\$//; s#\\s+#\\t#g;' file");
实际上,为什么要调用shell?
system('perl', '-i', '-ple' 's/^\\s+//; s/\\s+$//; s#\\s+#\\t#g;', 'file');
答案 2 :(得分:1)
您忘记首先将反斜杠解析为Perl双引号字符串,然后再作为shell命令解析。
等同于命令行:
perl -pi -le 's/^\s+//; s/\s+$//; s#\s+#\t#g;' file
在Perl脚本中
system "perl -pi -le 's/^\\s+//; s/\\s+\$//; s#\\s+#\\t#g;' file"
虽然为此启动另一个Perl副本是愚蠢的。你可能最好再使用几行代码并在同一个过程中完成它。
答案 3 :(得分:1)
runrig展示了如何使用-i不必创建子进程。在内部使用-i有点奇怪,所以有两个更清晰的选择。第一种是使用Tie::File,这非常简单。
另一种是使用File::Temp写入临时文件,这基本上就是-i所做的。
my $tmp = File::Temp->new;
open my $fh, "<", $file or die "Can't open $file: $!";
while(<$fh>) {
s/.../.../;
print $tmp $_;
}
my $tmpfile = $tmp->filename;
rename $tmpfile, $file or die "Can't rename $tmpfile to $file: $!";
答案 4 :(得分:0)
内部双引号'
具有否功能值。您的字符串将由Perl编辑。我的测试显示您丢失了\s
个表达式。它还插入了'\t'
。选项卡 - 虽然这可能不是问题所在。
以下是Data::Dumper
:
$s = 'perl -pi -le \'s/^s+//; s/s+$//; s#s+# #g;\' file';
答案 5 :(得分:0)
双引号正在解释一切。
尝试:
system "perl -pi -le 's/^\\s+//; s/\\s+\$//; s\#\\s+\#\\t\#g;' file";
答案 6 :(得分:0)
for Linux try
system q(perl -pi -le 's/^\s+//; s/\s+$//; s#\s+#\t#g;' file); # comments here
for M $ windows:
system q(perl -pi -le "s/^\s+//; s/\s+$//; s#\s+#\t#g;" file); # comments here
答案 7 :(得分:0)
这就是Larry为我们提供备用引号字符的情况。我们想对system()s arg使用单引号,这样我们就不必弄清楚需要反斜杠的内容,但我们在引用的字符串本身中也需要单引号。所以,替代引用字符来救援!
system q(perl -p -le 's/^\s+//; s/\s+$//; s#\s+#\t#g;' file);
现在,您可以将在命令行中工作的内容直接复制/粘贴到Perl源中。