一連の文字列とその置換がスペースで区切られています。
a123 b312
c345 d453
左の列の文字列を右の列の文字列に置き換えて、後で元に戻したいです。最初の部分では、sed コマンド s/.../...;s/.../... を作成できましたが、それは反転を考慮していないため、入力を大幅に変更する必要があり、時間がかかります。 . これを行う便利な方法はありますか?
いくつかのサンプル プログラムをリストしました。
一連の文字列とその置換がスペースで区切られています。
a123 b312
c345 d453
左の列の文字列を右の列の文字列に置き換えて、後で元に戻したいです。最初の部分では、sed コマンド s/.../...;s/.../... を作成できましたが、それは反転を考慮していないため、入力を大幅に変更する必要があり、時間がかかります。 . これを行う便利な方法はありますか?
いくつかのサンプル プログラムをリストしました。
テキスト エディタには「元に戻す」機能がありますが、コマンド ライン ユーティリティにはありません。置換を行うスクリプトを作成してから、置換ファイルを逆にして同じことを逆に行うことができます。
「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