添加代码行的perl脚本只修改一个文件

时间:2014-06-19 21:15:04

标签: perl

我有这个:

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脚本,因为没有那么多,但不想手动编辑每个文件。

3 个答案:

答案 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项健全性检查,以验证事情是否按照您想要的方式进行处理。

  1. 最初,脚本将打印出找到的文件,直到你注释掉裸露的回报。
  2. 然后,除非取消注释unlink语句,否则脚本将保存备份。
  3. 最后,脚本将只处理单个文件,直到您注释掉exit语句。
  4. 这三项检查只是为了在编辑整个目录树之前验证所有内容是否正常工作。

    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 
    }, '.')