1

一連の文字列とその置換がスペースで区切られています。

a123 b312
c345 d453

左の列の文字列を右の列の文字列に置き換えて、後で元に戻したいです。最初の部分では、sed コマンド s/.../...;s/.../... を作成できましたが、それは反転を考慮していないため、入力を大幅に変更する必要があり、時間がかかります。 . これを行う便利な方法はありますか?

いくつかのサンプル プログラムをリストしました。

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 に答える