파일이 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이 구출하러 옵니다!
교체 쌍을 해시로 읽어옵니다. 그런 다음 입력을 한 줄씩 읽고 일치 항목을 바꾸십시오.
#!/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