0

嗨,我正在尝试用以下字符串替换文件 test.txt 中的字符串:

  <g
   id="g16526">
  <g

  <g
   id="gnnnnn">
  <g

并将它们变成

  <g
   id="gg1">
  <g
   ...
  <g
   id="ggn">
  <g

使用这个 perl 脚本

    #!C:/Strawberry/perl
    open(FILE, "<test.txt") || die "File not found";
    my @lines = <FILE>;
    close(FILE);
    my $string = '<g
    id=';
    my $string2 = '<g
    <g'; 
    my $anything = ".*";

    my $replace = 'gg';
    my @newlines;
    my $counter = 1;

    foreach(@lines) {
      $_ =~ s/\Qstring$anything\Q$string2/$string$replace$string2$counter/g;
      $counter++;
      push(@newlines,$_);
    }

    open(FILE, ">test.txt") || die "File not found";
    print FILE @newlines;
    close(FILE);

但它不起作用,任何建议表示赞赏

4

1 回答 1

1

如果这确实具有看起来像 XML 的结构,则应该使用模块对其进行处理,无论是XML::LibXML还是XML::Twig

但是如图所示的这项任务也很容易以基本的方式完成

perl -0777 -wpE'
    BEGIN { $cnt = 0 };
    s/<g\nid="g\K(.*?)"/q(g).(++$cnt).q(")/eg;
' input.txt

它期望文件格式完全如图所示。它将整个文件读入一个字符串 by -0777,这不是最漂亮的,并且可能不适合非常大的文件。

另一种方法是将记录分隔符设置为<g,因此每个“行”都是要处理的块

perl -wpE'
    BEGIN { local $/ = "<g"; $cnt = 0 }; 
    s/id="g\K(.*?)"/q(g).++$cnt.q(")/eg; 
' input.txt

现在正则表达式可以自由精确地搜索id="...",我们可以逐行处理。

这些都打印预期的输出。它们是单行的,以便于测试,我建议转移到脚本。

于 2017-09-16T20:09:40.903 回答