我有一系列字符串和它们的替换用空格分隔:
a123 b312
c345 d453
我想用右列中的字符串替换左列中的那些字符串,然后撤消替换。对于第一部分,我可以构建一个 sed 命令 s/.../...;s/.../... 但这不考虑反转,它需要我显着改变输入,这需要时间. 有没有方便的方法来做到这一点?
列出了一些示例程序,可以是任何免费的 win/lin。
我有一系列字符串和它们的替换用空格分隔:
a123 b312
c345 d453
我想用右列中的字符串替换左列中的那些字符串,然后撤消替换。对于第一部分,我可以构建一个 sed 命令 s/.../...;s/.../... 但这不考虑反转,它需要我显着改变输入,这需要时间. 有没有方便的方法来做到这一点?
列出了一些示例程序,可以是任何免费的 win/lin。
文本编辑器提供“撤消”功能,但命令行实用程序不提供。您可以编写一个脚本来进行替换,然后反转替换文件以反向执行相同的操作。
这是一个脚本,它在“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 脚本以使用反向替换文件而不是正向替换文件。
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