我正在尝试替换多个文件中的字符串。但只有第一个文件被替换。代码是:
perl -pi -e 's/(^<section_begin>.*\s+$)/\1<expand>\n/ if $.==1' *exp`
grep -iw "expand" *exp
a3exp:<expand>
如果我对单个文件使用相同的命令,它正在工作:
perl -pi -e 's/(^<section_begin>.*\s+$)/\1<expand>\n/ if $.==1' n2exp
grep -iw "expand" *exp
a3exp:<expand>
n2exp:<expand>
你能帮我解决这个问题吗?
答案 0 :(得分:4)
根据perlvar:
$。文件句柄关闭时重置,但重新打开文件句柄时没有插入关闭(),不。
因为&#34;&lt;&gt;&#34;从不在ARGV文件中明确关闭,行数增加(但请参阅eof中的示例)。
(第二个重点补充)
使用-p
时,@ARGV
设置为您在命令行上传递的文件列表。由于在转到下一个文件时未重置$.
,因此对于第一个文件,它仅等于1。您只需打印$.
:
$ echo foo > foo
$ echo bar > bar
$ perl -pe 'print "$. "' *
1 bar
2 foo
(-p
行自动打印,因此在上面的示例中,每行的内容都打印在$.
)的旁边
当您mpapec suggests移动到下一个文件时close
特殊文件句柄ARGV
,$.
将按您的预期行事:
$ perl -pe 'print "$. "; close ARGV if eof' *
1 bar
1 foo
有关更多详细信息和一些很好的示例,请参阅documentation for eof。
答案 1 :(得分:3)
关闭ARGV
文件句柄后,行计数器$.
会重置。
http://perldoc.perl.org/perlvar.html#ARGV
在@ARGV
中迭代命令行文件名的特殊文件句柄
因此,您需要在到达eof()
时明确关闭文件,
perl -pi -e'
s/(^<section_begin>.*\s+$)/\1<expand>\n/ if $.==1;
close ARGV if eof;
' *exp
答案 2 :(得分:2)
Unix shell有很多工具可以解决这个问题。有find
的{{1}}:
-exec
或老式的find . -name \*exp -exec perl -pi -e '... if $.==1' {} \;
循环。在for
中看起来像
bash
答案 3 :(得分:2)
您可以使用eof
或eof(ARG)
检测每个文件的结尾并重置$.
。
来自文档
在while(&lt;&gt;)循环中,eof或eof(ARGV)可用于检测每个文件的结尾,而eof()将仅检测最后一个文件的结尾。例子:
# reset line numbering on each input file
while (<>) {
next if /^\s*#/; # skip comments
print "$.\t$_";
} continue {
close ARGV if eof; # Not eof()!
}
答案 4 :(得分:0)
我认为你的if。== 1会让你。处理了这些行:你告诉它只处理输入的第一行。