我有一系列字符串,它们的替换用空格分隔:
a123 b312
c345 d453
我想将左列中的字符串替换为右列中的字符串,稍后撤消替换。对于第一部分,我可以构造一个sed命令s / ... / ...; s / ... / ...但不考虑反转,它需要我显着改变输入,这需要时间。有没有方便的方法呢?
列出了一些示例程序,可以为win / lin免费提供任何内容。
答案 0 :(得分: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脚本以使用反向替换文件而不是前向文件。
答案 1 :(得分: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
将阻止部分匹配,例如将a12345
替换为b31245
。在$rx
中,您可能希望转义元字符,如果替换中存在元字符。
<强>用法:强>
执行替换:
script.pl 0 replace.txt input.txt > output.txt
要撤消更改:
script.pl 1 replace.txt output.txt > output2.txt