텍스트 파일의 태그를 임의의 새 텍스트로 교체

텍스트 파일의 태그를 임의의 새 텍스트로 교체

일부 텍스트와 새 콘텐츠를 추가해야 하는 위치를 나타내는 표시가 한 줄에 포함된 파일이 있습니다.

foo
bar
%SUBSTITUTE%
foo

한 줄씩 대체하는 내용은 새로운 여러 줄 문자열로 대체되어야 합니다 text="some text"(문자열을 모른다는 점에 유의하세요. 예를 들어 cat "file" 파일을 읽은 결과일 수 있습니다 text=). 대체 결과는 다음과 같아야합니다.

foo
bar
some text
%SUBSTITUTE%
foo

작동이 중지 된 작업 버전이 있었습니다 perl(분명히 Perl 버전 변경으로 인해). 이제 tr및 같은 표준 유틸리티를 사용하여 sed해당 줄을 바꾸려고 합니다 . 붙여넣는 문자열에 백슬래시 등 임의의 문자가 포함될 수 있기 때문에 문제가 발생했습니다. 붙여넣기 전에 이러한 문자를 이스케이프 처리하고 싶지 않습니다.

표준 도구를 사용하여 이를 수행하는 안전한 방법이 있습니까? 이 문제에 대해 제가 발견한 다른 문제는 붙여넣은 것으로 알려진 텍스트에 대한 특정 솔루션입니다.

답변1

sed의 GNU 버전이 있는 경우 해당 r명령을 사용하여 파일에서 읽고 새 내용을 삽입한 다음 표시된 줄을 삭제할 수 있습니다.

sed '/%SUBSTITUTE%/{
r path/to/newcontent
d
}' file

%SUBSTITUTE%태그를 유지하고 싶다면뒤쪽에삽입하세요. 무엇을 하든 GNU r확장은 파일 내용을 대기열에 넣을 것이기 때문에 까다롭습니다.현재 모드 주기(계속 유지)앞으로명령 을 제거하면 됩니다 d.) 아마도 가장 쉬운 방법은 파일에 추가하는 것입니다 newcontent. 다음과 같이 즉시 수행할 수 있습니다.

sed '/%SUBSTITUTE%/{
r /dev/stdin
d
}' file < <(sed '$a %SUBSTITUTE%' path/to/newcontent)

완전히 다른 접근 방식을 사용하면 첫 번째 파일을 분할 %SUBSTITUTE%한 다음 새 콘텐츠를 추가 할 수 있습니다.

csplit -s file '/%SUBSTITUTE%/'
cat xx00 newcontent xx01

첫 번째 파일의 줄에 대해 bash 루프를 수행하고 태그 문자열이 일치할 때 새 파일의 내용을 캡처 할 수도 있습니다 read. 그러나 이 포럼에서 제안한 대로 텍스트 처리를 위한 루프를 읽는 것이 이미 불안합니다. 불행히도 둘 다 적절한 솔루션을 제공하지 않습니다.

답변2

이를 사용하는 또 다른 방법이 있습니다 ed. 태그 앞에 삽입된 모든 항목
(즉, 포함하는 줄 앞):FILE%SUBSTITUTE%

ed -s originalfile <<< $'/%SUBSTITUTE%/- r FILE\nw\nq'

여기서:
/%SUBSTITUTE%/: 일치하는 첫 번째 줄에 주소를 설정 %SUBSTITUTE%
-하거나: -1한 줄 앞의 주소를 오프셋합니다. : : 쓰기(쓰기 대신 내용을 인쇄하는 것으로 대체됨): 편집기 종료
r FILEReads FILE to after the addressed line.
woriginalfile,p
q

FILE태그 앞에 !echo "$TEXT"삽입될 항목 으로 바꾸세요 .$TEXT

export TEXT
ed -s originalfile <<'IN'
/%SUBSTITUTE%/-1 r !echo "$TEXT"
w
q
IN

답변3

나는 다음을 기반으로 솔루션을 찾았습니다 awk.

text=`cat "filepaste"`
export text;
<"$file" awk '
    BEGIN {REPLACE=ENVIRON["text"] "\n%SUBSTITUTE%" }
    {gsub(/^%SUBSTITUTE%$/, REPLACE); print}
'

여기서 "filepaste"에는 대체할 콘텐츠가 포함되어 있습니다 %SUBSTITUTE%. 한 가지 장점은 문자열을 파일에 다시 저장하지 않고도 다양한 셸 도구를 사용하여 문자열을 조작할 수 있다는 것입니다. 환경 변수에서 awk변수를 읽으면 REPLACE확장 시 이스케이프 문자가 방지됩니다 text.

답변4

이제 Perl 솔루션이 있으므로 여기에 또 다른 솔루션이 있습니다. 나는 rep.txt교체품을 저장하는 데 사용합니다.

$ perl -pe '$re=`cat rep.txt`; chomp($re); s/%SUBSTITUTE%\n/$re/' file.txt
foo
bar
multi
  line
string
foo

대상 파일의 각 줄을 읽고( file.txt), 주어진 스크립트를 -e여기에 적용하고 인쇄합니다( -p).

관련 정보