我有这个:
perl -pi -e 'print "code I want to insert\n" if $. == 2' *.php
将行code I want to insert
放在文件的第二行,这是我需要对每个PHP文件执行的操作
如果我在包含PHP文件和非PHP文件的目录中运行它,它会做正确的事情,但只能用于一个PHP文件。我以为*.php
会将它应用于所有PHP文件,但它不会这样做。
如何编写它以便修改目录中的每个PHP文件?如果有一种简单的方法可以通过所有目录递归执行此操作,则可以获得奖励。我不介意为每个目录运行Perl脚本,因为没有那么多,但不想手动编辑每个文件。
答案 0 :(得分:2)
问题是Perl用来读取命令行上传递的文件的文件句柄ARGV
从未显式关闭,因此行号$.
在第一个文件结束后继续递增文件,永远不会回到一个。
通过在文件结束时关闭ARGV
来解决此问题。 Perl将重新打开它以读取列表中的下一个文件,因此重置$.
perl -i -pe 'print "code I want to insert\n" if $. == 2; close ARGV if eof' *.php
答案 1 :(得分:1)
如果你可以使用sed
,这应该可行:
sed -si '2i\CODE YOU WANT TO INSERT' *.php
要递归地执行此操作,您可以尝试:
find -name '*.php' -execdir sed -si '2i\CODE YOU WANT TO INSERT' '{}' +
答案 2 :(得分:1)
使用File::Find
。
请注意,我已经进行了3项健全性检查,以验证事情是否按照您想要的方式进行处理。
exit
语句。这三项检查只是为了在编辑整个目录树之前验证所有内容是否正常工作。
use strict;
use warnings;
use File::Find;
my $to_insert = "code I want to insert\n";
find(sub {
return unless -f && /\.php$/;
print "Edit $File::Find::name\n";
return; # Comment out once satisfied with found files
local $^I = '.bak';
local @ARGV = $_;
while (<>) {
print $to_insert if $. == 2 && $_ ne $to_insert;
print;
}
# unlink "$_$^I"; # Uncomment to delete backups once certain that first file is processed correctly.
exit; # Comment out once certain that first file is processed correctly
}, '.')