ファイルが3つあります。
~/naive-file.txt
~/old-text.txt
~/new-text.txt
~/old-text.txt
に表示されるすべてのコンテンツインスタンスを見つけて、そのアイテムを~/naive-file.txt
のコンテンツに置き換えたいと思います~/new-text.txt
。私はこれがsed
orを使って達成できると確信していますawk
が、正しいコマンドを見つけることができないようです。可能ですか?
たとえば、コンテンツが~/naive-file.txt
次のようになっているとします。
$ cat ~/naive-file.txt
Sed id ligula quis est convallis tempor.
This is the old text.
It might have multiple lines and some special characters like these \ { & % #)!
etc...
Nunc aliquet, augue nec adipiscing interdum, lacus tellus malesuada massa, quis
varius mi purus non odio.
内容~/old-text.txt
が次のとおりです。
$ cat ~/old-text.txt
This is the old text.
It might have multiple lines and some special characters like these \ { & % #)!
etc...
内容~/new-text.txt
が次のとおりです。
$ cat ~/new-text.txt
This is the new text.
It could also have multiple lines and special characters like these \ { & %
etc...
私が望むコマンドを実行すると
Sed id ligula quis est convallis tempor.
This is the new text.
It could also have multiple lines and special characters like these \ { & %
etc...
Nunc aliquet, augue nec adipiscing interdum, lacus tellus malesuada massa, quis
varius mi purus non odio.
ベストアンサー1
Perlが救出に来る!
交換ペアをハッシュとして読み込みます。次に、入力を1行ずつ読み、一致を置き換えます。
#!/usr/bin/perl
use warnings;
use strict;
open my $ot, '<', 'old-text.txt' or die $!;
chomp( my @lines = <$ot> );
open my $nt, '<', 'new-text.txt' or die $!;
my %replace;
@replace{@lines} = <$nt>;
chomp for values %replace;
my $regex = join '|', map quotemeta, @lines;
open my $in, 'naive-file.txt' or die $!;
while (<$in>) {
s/($regex)/$replace{$1}/;
print;
}
置換する文字列の一部が置換する他の文字列の部分文字列である場合は、正規表現で文字列を長さの降順で並べ替える必要があります。
my $regex = join '|', map quotemeta, sort { length $b <=> length $a } @lines;