2

内部文本文件

Letter A = "AAA"
Letter B = "BBB"

我尝试:

perl -p -e 's/(Letter A \=)(.*\")(\n+)(Letter B \=)/$1$2$3$4/g' text

但它不起作用。问题似乎在\n.

任何想法?

其实我想换个词,怎么办?
从:
字母 A = “AAA”
字母 B = “BBB”
至:
字母 A = “BBB”
字母 B = “AAA”

如果两行之间有其他单词。还有其他解决方案吗?

ABCABC
字母 A = "BBB"
字母 B = "AAA"
DSAAS
TRQWTR
字母 C = "DDD"
字母 D = "CCC"
SDAGER
LPITET

4

3 回答 3

6

-p将输入拆分为行,这意味着您的模式将永远不会在\n任何地方看到 a ,而是在它正在查看的文本的末尾。如果要进行多行匹配,则需要编写一个实际脚本或更改输入记录分隔符,使其不会按行拆分(可能-0777使用“slurp”模式)。

perl -0777 -p -e 's/(Letter A =)(.*")(\n+)(Letter B =)/$1 Hello$2$3$4 Hello/' test2
Letter A = Hello "AAA"
Letter B = Hello "BBB"
于 2012-04-24T07:16:36.320 回答
0

如果你把它放到一个小程序中,你可以做这样的事情。顶部注释掉的部分表明它适用于不止一对线。不过,按照我构建它的方式,您必须通过管道输入文本文件。

# my $text = qq~Letter A = "AAA"
# Letter B = "BBB"
# Letter C = "CCC"
# Letter D = "DDD"~;
# 
# my @temp = split /\n/, $text;
my @temp = <>;

for (my $i=0; $i <= $#temp; $i+=2) {
  $temp[$i] =~ m/"(\w+)"/;
  my $w1 = $1;
  $temp[$i+1] =~ s/"(\w+)"/"$w1"/;
  my $w2 = $1;
  $temp[$i] =~ s/"$w1"/"$w2"/;
}
print join "\n", @temp;

输出:

Letter A = "BBB"
Letter B = "AAA"
Letter C = "DDD"
Letter D = "CCC"

如果中间可以有其他行,这就是代码的样子。

my $text = qq~Letter A = "AAA"
testtesttest
Letter B = "BBB"
loads 
of text
Letter C = "CCC"
Letter D = "DDD"
Letter E = "EEE"

Letter F = "FFF"~;

my @temp = split /\n/, $text;
# my @temp = <>;

my $last_index; # use this to remember where the last 'fist line' was
for (my $i=0; $i <= $#temp; $i+=1) {
  if (!defined $last_index) {
    # if we have not find a 'first line' yet, look if this is it
    $last_index = $i if $temp[$i] =~ m/"(\w+)"/;
  } elsif ($temp[$i] =~ m/"(\w+)"/) {
    # otherwhise if we already have a 'first line', check if this is a 'second line'
    $temp[$last_index] =~ m/"(\w+)"/; # use the 'first line'
    my $w1 = $1; 
    $temp[$i] =~ s/"(\w+)"/"$w1"/; # and the current line
    my $w2 = $1;
    $temp[$last_index] =~ s/"$w1"/"$w2"/;
    $last_index = undef; # remember to reset the 'first line'
  }
}
print join "\n", @temp;

输出:

Letter A = "BBB"
testtesttest
Letter B = "AAA"
loads 
of text
Letter C = "DDD"
Letter D = "CCC"
Letter E = "FFF"

Letter F = "EEE"
于 2012-04-24T08:40:16.620 回答
-1

我想你需要这个。试试看

perl -pe 's/$\\n/Hello/g' filename

输出

[tethomas@~/Perl]cat t
Letter A = "AAA"
Letter B = "BBB"
[tethomas@~/Perl]perl -pe 's/$\\n/Hello/g' t
Letter A = "AAA"HelloLetter B = "BBB"Hello
于 2012-04-24T07:49:18.283 回答