あるファイルの内容全体に一致するテキストを別のファイルの内容全体に置き換える効率的な方法はありますか?

あるファイルの内容全体に一致するテキストを別のファイルの内容全体に置き換える効率的な方法はありますか?

ファイルが3つあります。

~/naive-file.txt
~/old-text.txt
~/new-text.txt

~/old-text.txtに表示されるすべてのコンテンツインスタンスを見つけて、そのアイテムを~/naive-file.txtのコンテンツに置き換えたいと思います~/new-text.txt。私はこれがsedorを使って達成できると確信しています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;

おすすめ記事