【问题标题】:Perl search file recursive for string and replacePerl搜索文件递归字符串并替换
【发布时间】:2016-10-28 12:08:46
【问题描述】:

在带有 perl 的终端中,我如何搜索从当前工作目录开始递归的所有 php 文件以查找单行或多行模式,例如:

<script>var a=''; * hamoorabi.com * </script>

类似:查找&lt;script&gt;var a='';&lt;/script&gt;之间的所有内容,但前提是包含hamoorabi.com并将其替换为空字符串(删除它)。

由于它是 javascript 代码,因此搜索字符串中可能会有一堆未转义的字符。

【问题讨论】:

  • 这部分是递归的?找到文件?更多地谈论如何找到您想要更改的文件,并展示您尝试过的内容以及遇到问题的地方
  • 我编辑了我的问题的文件 ;)
  • 这里的替换部分就像my $beginning = '&lt;script&gt;var a=\'\''; my $end = '&lt;/script&gt;'; my $containing = 'hamoorabi.com'; s/\Q$beginning\E(?:(?!\Q$end\E).)*\Q$containing\E.*?\Q$end\E//g;(未经测试)
  • 什么操作系统?
  • 这是 Debian 3.2.73-2+deb7u2 x86_64 GNU/Linux

标签: perl


【解决方案1】:

从 unix 或 cwygin 提示符:

$ find . | grep .php | xargs ./xx1.pl

perl 脚本 xx1.pl 在哪里:

#!/usr/bin/perl

use strict;
use warnings;

undef $/;
for (@ARGV) {
        open(FILE,$_);
        my $content = <FILE>;
        close(FILE);
        my $beginning = '<script>var a=\'\'';
        my $end = '</script>';
        my $containing = 'hamoorabi.com';
        #$content =~ s/(<script>.*?)(hamoorabi.com)(.*?<\/script>)/$1$3/sg;
        #much better regex provided by ysth
        $content =~ s/\Q$beginning\E(?:(?!\Q$end\E).)*\Q$containing\E.*?\Q$end\E//gs;
        open(FILE,">$_");
        print FILE $content;
        close(FILE);
}

【讨论】:

  • 谢谢!这看起来非常干净和漂亮,不幸的是它只替换了 hamoorabi.com 而不是整个字符串,意思是 &lt;script&gt;*.*&lt;/script&gt; 可以这样做吗?
  • 啊,阅读前请三思。 $content =~ s/(&lt;script&gt;.*?)(hamoorabi.com)(.*?&lt;\/script&gt;)//sg; 应该这样做 ;)
  • 这将删除不包含 hamoorabi.com 的脚本(如果文件中有更高版本的 hamoorabi.com)和它们之后的其他内容。请参阅我对问题的评论以获得更好的正则表达式。
  • 更多想法:它是 Cygwin!请在您的代码中使用尽可能多的空行来帮助解释您的思考过程。不要将整个文件读入标量变量,除非你有一个很好的借口(可能读入数组,但也很少读入)。如果您无论如何都在调用perl永远不要使用琐碎的 bash 命令行实用程序。谢天谢地,我想是这样的。
  • 哦,用叙述来解释你的代码。 “来自 unix 或 cwygin 提示符”“perl 脚本 xx1.pl 在哪里:” 只字不提你做出决定的原因或解释你所写的内容。一般来说,仅仅让程序“工作”几乎没有意义。写一些可见和可理解的东西总是更有用,并解释设计,这样你的团队中的任何一个人都可以拿起它,理解它,并用很少的努力让它工作。
【解决方案2】:

使用File::Find 遍历目录树以查找文件。

use strict;
use warnings;
use File::Find;

sub wanted {
  # Ignore anything that isn't a file
  return unless -f;
  # Ignore anything without a .php extension
  return unless /\.php$/;

  # Your filename is in $_. Your current directory is the 
  # one which contains the current file.
  # Do what you need to do.
  open my $fh, '<', $_ or die $!;
  ...;
}

【讨论】:

    【解决方案3】:

    我希望这也有助于进一步使用。

    use strict;
    use warnings;
    

    字符串替换 Regex 表单

    my $str = "<script>var a=''\; * hamoorabi.com * </script>";
    $str=~s#<script[^>]*>((?:(?!<\/script>).)*)<\/script># my $script=$&;
    $script=~s/^(.*)hamoorabi\.com(.*)$/$1$2/g;
    ($script);
    #esg;
    print $str;
    

    使用Tie::File替换同一文件上的内容

    my @array;
    use Tie::File;
    tie @array, 'Tie::File', "Input.php" || die "blabla";
    my $len = join "\n", @array;
    @array = split/\n/, $len;
    untie @array;
    

    【讨论】:

      猜你喜欢
      • 2015-10-03
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2011-09-25
      • 2011-09-27
      • 2020-01-06
      相关资源
      最近更新 更多