1

我有一系列字符串和它们的替换用空格分隔:

a123 b312
c345 d453

我想用右列中的字符串替换左列中的那些字符串,然后撤消替换。对于第一部分,我可以构建一个 sed 命令 s/.../...;s/.../... 但这不考虑反转,它需要我显着改变输入,这需要时间. 有没有方便的方法来做到这一点?

列出了一些示例程序,可以是任何免费的 win/lin。

4

2 回答 2

1

文本编辑器提供“撤消”功能,但命令行实用程序不提供。您可以编写一个脚本来进行替换,然后反转替换文件以反向执行相同的操作。

这是一个脚本,它在“replacements.txt”中进行一系列替换,并根据脚本的输入运行它们:

#!/usr/bin/perl -w

use strict;

open REPL, "<replacements.txt";
my @replacements;
while (<REPL>) {
    chomp;
    push @replacements, [ split ];
}
close REPL;

while (<>) {
    for my $r (@replacements) { s/$r->[0]/$r->[1]/g }
    print;
}

如果将此文件保存为“repl.pl”,并将上面的文件保存为“replacements.txt”,则可以这样使用它:

perl repl.pl input.txt >output.txt

要将替换文件转换为“reverse-replacements.txt”文件,可以使用简单的 awk 命令:

awk '{ print $2, $1 }' replacements.txt >reverse-replacements.txt

然后只需修改 Perl 脚本以使用反向替换文件而不是正向替换文件。

于 2012-05-13T05:35:36.177 回答
0
use strict;
use warnings;

unless (@ARGV == 3) {
    print "Usage: script.pl <reverse_changes?> <rfile> <input>\n";
    exit;
}
my $reverse_changes = shift;
my $rfile = shift;
open my $fh, "<", $rfile or die $!;
my %reps  = map split, <$fh>;

if ($reverse_changes) {
    %reps = reverse %reps;
}

my $rx = join "|", keys %reps;

while (<>) {
    s/\b($rx)\b/$reps{$1}/g;
    print;
}

\b围绕替换的单词边界检查将防止部分匹配,例如替换a12345b31245. 在$rx你可能希望转义元字符,如果这样可以出现在你的替代品中。

用法:

要执行替换:

script.pl 0 replace.txt input.txt > output.txt

要反转更改:

script.pl 1 replace.txt output.txt > output2.txt
于 2012-05-13T05:46:11.930 回答