텍스트 파일의 마커를 임의의 새 텍스트로 교체

텍스트 파일의 마커를 임의의 새 텍스트로 교체

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

foo
bar
%SUBSTITUTE%
foo

줄 line 대체는 새로운 여러 줄 문자열로 대체되어야 합니다 (예를 들어 cat "file"`` text="some text"파일을 읽은 결과일 수 있는 문자열을 모른다는 점에 유의하세요 ). 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루프를 수행하고 마커 문자열과 일치할 때 새 콘텐츠 파일을 cat할 수도 있습니다. 그러나 저는 이 포럼에서 텍스트 처리를 위한 읽기 루프를 제안한 것에 대해 손가락질을 받았습니다. 불행히도 둘 다 적절한 솔루션을 제공하지 않습니다.

답변2

를 사용하는 또 다른 방법이 있습니다 ed. 마커 앞에
의 전체 내용을 삽입합니다 (예: 를 포함하는 줄 앞에 ).FILE%SUBSTITUTE%

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

여기서:
/%SUBSTITUTE%/: 일치하는 첫 번째 줄에 주소를 설정 %SUBSTITUTE%
-하거나 -1: 오프셋은 한 줄 앞의 주소를 설정합니다
r FILE. Reads FILE to after the addressed line.
w: : 쓰기 originalfile( ,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변수 를 읽으면 에서 이스케이프 문자가 확장되는 것을 방지할 수 있습니다 .REPLACEtext

답변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).

관련 정보