여러 줄 변수가 있는 쉘 스크립트에서 sed 사용

여러 줄 변수가 있는 쉘 스크립트에서 sed 사용

저는 쉘 스크립트를 사용하여 다양한 유형의 VM을 설정합니다. 종종 이러한 스크립트에는 를 사용하여 특정 위치의 구성 파일에 삽입해야 하는 여러 줄 변수가 포함됩니다 sed.

이렇게 만들면 모든 것이 괜찮습니다.

VAR="Config Line1\nConfig Line2\nConfig Line 3"
sed -i "/MatchingPattern/ a $VAR" somefile

하지만 특히 텍스트 블록이 상당히 길 수 있기 때문에 스크립트를 읽기가 쉽지 않습니다.

내가 다음과 같이 쓴다면:

VAR="Config Line1
Config Line2
Config Line 3"
sed -i "/MatchingPattern/ a $VAR" somefile

스크립트를 실행할 때 오류가 발생합니다: sed: -e expression #1, char 31: unknown command:C'`

sed이렇게 선언된 변수를 사용할 수 있는 방법이 있나요 ?

답변1

명령 의 표준 구문은 다음 a과 같습니다.

sed -e 'a\
first line\
  second line\
last line'

BSD(적어도 FreeBSD 및 OS/X)는 sed선행 공백을 제거합니다., 그리고-e버그를 해결하려면 이 필요합니다.. GNU에서는 비어 있지 않은 한 sed첫 번째 줄을 바로 다음 줄로 이동할 수 있습니다 .a\

따라서 입력을 전처리해야 합니다.

VAR='content with
multiple lines
  some with lead blanks
or even backslash\'

preprocessed_VAR=$(printf '%s\n' "$VAR" |
  sed 's/\\/&&/g;s/^[[:blank:]]/\\&/;s/$/\\/')

sed -i -e "/MatchingPattern/a\\
${preprocessed_VAR%?}" somefile

( FreeBSD 또는 OS/X에서는 -i로 대체 -i '').

GNU/Linux 및 GNU 셸( bash) 또는 에서는 zsh다음을 대신 수행할 수 있습니다.

sed -i '/MatchingPattern/r /dev/stdin' <<< "$VAR"

bash이는 삭제된 임시 파일과 함께 here-strings를 구현 하고 Linux의 /dev/stdin이 파일에 대한 심볼릭 링크로 구현되기 때문에 작동합니다 zsh(즉, 여러 번 열 수 있고 매번 처음에 열림).

여기서 대신 GNU를 사용할 수도 있습니다 awk.

(export VAR
gawk -i /usr/share/awk/inplace.awk '{print}; /MatchingPattern/{print ENVIRON["VAR"]}' somefile)

사용하지 마세요-i inplaceas 는 누군가 악성 코드를 심었을 수 있는 현재 작업 디렉터리에서 확장명(as 또는 )을 먼저 gawk로드하려고 시도합니다 . 와 함께 제공되는 확장 프로그램 의 경로는 시스템에 따라 다를 수 있습니다.inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

또는 perl(어디 -i에서 나온 것인지):

(export VAR
perl -pi -e '$_ .= "$ENV{VAR}\n" if /MatchingPattern/' somefile)

답변2

이 오류는 실제 뒤에 백슬래시가 필요한 sed추가 명령 으로 인해 발생합니다 .aa

GNU를 사용하면 sed:

$ sed "/pattern/a\\$VAR" file.in >file.out

BSD sed는 내가 아는 a한 줄 바꿈이 제대로 이스케이프되지 않는 한 명령을 사용하여 파일에 한 줄만 삽입할 수 있습니다.

BSD로 이 문제를 해결하는 방법에 대한 밀접하게 관련된 답변은 다음과 같습니다 sed.http://unix.stackexchange.com/a/60322

관련 정보