한 파일의 전체 내용과 일치하는 텍스트를 다른 파일의 전체 내용으로 바꾸는 효율적인 방법이 있습니까?

한 파일의 전체 내용과 일치하는 텍스트를 다른 파일의 전체 내용으로 바꾸는 효율적인 방법이 있습니까?

파일이 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이 구출하러 옵니다!

교체 쌍을 해시로 읽어옵니다. 그런 다음 입력을 한 줄씩 읽고 일치 항목을 바꾸십시오.

#!/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;

답변2

불다

첫 번째 일치 항목을 바꿉니다.

target=$(cat naive-file.txt)
old=$(cat old-text.txt)
new=$(cat new-text.txt)
echo "${target/"$old"/"$new"}"

모든 일치 항목 바꾸기:

echo "${target//"$old"/"$new"}"

시작 일치 교체:

echo "${target/#"$old"/"$new"}"

최종 일치 항목 바꾸기:

echo "${target/%"$old"/"$new"}"

답변3

이것은 GNU의 인용문입니다 awk:

awk 'NR==FNR{old[++k]=$0}FILENAME=="new-text.txt"{new[FNR]=$0}
     FILENAME=="naive-file.txt"{for(i=1;i<k;i++)if(old[i]==$0)$0=new[i];print}'\
     old-text.txt new-text.txt naive-file.txt

모든 패턴이 먼저 배열에 저장되므로 매우 큰 파일에는 적합하지 않을 수 있습니다.

산출:

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.

답변4

$ perl -0777ne '
     $A[@ARGV] = $_;
     @ARGV and next;
     my($naive, $new, $old) = @A;
     while ( index($naive,$old,$p) > -1 ) {
        substr($naive, index($naive,$old,$p), length($old)) = $new;
        $p = index($naive,$old,length($old)) ;
      }
      print $naive;
' old.txt new.txt naive.txt

관련 정보