.png)
입력이 있습니다.
a
b TOCHANGE
c
d
e TOCHANGE
외부 파일을 사용하여 "TOCHANGE" 모드를 변경해야 합니다.
line1
line2
...
이렇게 하면 다음과 같은 결과를 얻습니다.
a
b line1
c
d
e line2
다음 명령을 시도했습니다.
while read k ; do sed -i "s/TOCHANGE/$k/g" input ; done < externalfile
하지만 나는 다음을 얻습니다.
a
b line1
c
d
e line1
답변1
그리고 perl
:
perl -pi -e 's{TOCHANGE}{chomp ($repl = <STDIN>); $repl}ge' input <externalfile
의 경우 다음에서 발생이 발생하지 않는 awk
것으로 가정됩니다 (또는 더 일반적으로 대체는 다음을 포함하는 입력에서 발생할 수 있는 것처럼 새 발생을 생성하지 않습니다 ).TOCHANGE
externalfile
TOCHANGE
TOTOCHANGE FROMTOCHANGE
externalfile
CHANGE
WHATEVER
POSIXLY_CORRECT=1 PAT=TOCHANGE awk '
{
while ($0 ~ ENVIRON["PAT"]) {
getline repl < "externalfile"
gsub(/[&\\]/, "\\\\&", repl)
sub(ENVIRON["PAT"], repl)
}
print
}' < input > input.new
( POSIXLY_CORRECT=1
GNU에서는 awk
이를 요구합니다. 그렇지 않으면 백슬래시 문자가 포함된 문자열을 제대로 바꿀 수 없습니다.)
위의 내용은 $PAT
확장 정규식으로 간주됩니다. 문자 그대로 처리하려면(예: 문자열 PAT='TO\.CHANGE'
대체 ) ERE 연산자를 이스케이프해야 할 수도 있습니다.TO.CHANGE
답변2
이는 다음과 같이 GNU sed를 사용하여 수행할 수 있습니다.
sed -e '/TOCHANGE/R file_2' input.txt |
sed -e '/TOCHANGE/N;s/TOCHANGE\(.*\)\n\(.*\)/\2\1/'
첫 번째 패스에서는sedfile_2 줄은 input.txt의 모든 줄에 대해 TOCHANGE 줄 아래에 배치됩니다.
다음 단계에서는 TOCHANGE가 포함된 줄이 다음 줄과 연결되고 as/// 대체를 통해 예상되는 출력이 제공됩니다.
그리고진주다음과 같이 구현할 수 있습니다.
perl -pe 's|TOCHANGE|<STDIN> =~ s/\n//r|e' input.txt < file_2
답변3
이걸로
awk -v old='TOCHANGE' '
NR==FNR{a[NR]=$0;next}
$2==old{$2=a[++i]}
1' changefile infile > outfile
답변4
까다로운 솔루션과 awk
특정 기능을 결합하세요.
첫 번째 변종
"TOCHANGE"
패턴이 각 행에서 한 번만 발생하는 경우 . 평소대로 awk
면 충분합니다.
awk '{
if(NF == 2) {
getline OFS < "file_2"
$1 = $1
}
print
}' FS='TOCHANGE' input.txt
두 번째 변형
"TOCHANGE"
패턴이 각 줄에 여러 번 나타날 수 있는 경우 . 필수의 gawk
.
gawk '{
RS="\n"
if(RT)
getline ORS < "file_2"
else
ORS=""
print
RS="TOCHANGE"
}' RS='TOCHANGE' input.txt
시험
입력.txt
a
b TOCHANGE
c
d
e TOCHANGE
f
g TOCHANGE
파일_2
line1
line2
line3
line4
산출
a
b line1
c
d
e line2
f
g line3