Perl 如何执行一系列字符串替换并能够轻松撤消它们?

Perl 如何执行一系列字符串替换并能够轻松撤消它们?,perl,sed,awk,str-replace,Perl,Sed,Awk,Str Replace,我有一系列字符串及其替换项,它们之间用空格分隔: a123 b312 c345 d453 我想将左列中的字符串替换为右列中的字符串,然后撤消替换。对于第一部分,我可以构造一个sed命令s/../。。。;s/../。。。但这并不考虑反转,它需要我显著改变输入,这需要时间。有什么方便的方法吗 列出了一些示例程序,win/lin可以免费使用。文本编辑器提供“撤消”功能,但命令行实用程序不提供。您可以编写一个脚本来执行替换,然后反转替换文件以反向执行相同的操作 下面是一个脚本,它在“replaceme

我有一系列字符串及其替换项,它们之间用空格分隔:

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;
}
要将替换文件转换为“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;
}
下面是一个脚本,它在“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;
}
要将替换文件转换为“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;
}
要反转更改,请执行以下操作:

script.pl 1 replace.txt output.txt > output2.txt
要反转更改,请执行以下操作:

script.pl 1 replace.txt output.txt > output2.txt

你的问题仍然太模糊,你无法得到高质量的答案,因为你没有陈述足够的关于你要做什么的信息。您是要在另一个文档中执行这些替换,还是只处理此处显示的信息?更换不保证是可逆的。例如,考虑当第二列中的两个项目相同时会发生什么情况,或者在进行替换之前,右侧列中的一个项目已经出现在输入中。如果您只需要交换这两列,这会容易得多。您只有一个文件吗?能否先创建文件的副本,进行替换,然后再从副本还原文件?我的输入(在另一个文档中)保证是可逆的。@Matt Ryall否,由于文件在这两个阶段之间进行了进一步的处理。您的问题仍然太模糊,无法获得高质量的答案,因为您没有陈述足够的关于您试图做什么的信息。您是要在另一个文档中执行这些替换,还是只处理此处显示的信息?更换不保证是可逆的。例如,考虑当第二列中的两个项目相同时会发生什么情况,或者在进行替换之前,右侧列中的一个项目已经出现在输入中。如果您只需要交换这两列,这会容易得多。您只有一个文件吗?能否先创建文件的副本,进行替换,然后再从副本还原文件?我的输入(在另一个文档中)保证是可逆的。@Matt Ryall否,因为文件在两个阶段之间进行进一步处理。