
저는 쉘 스크립트를 사용하여 다양한 유형의 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 inplace
as 는 누군가 악성 코드를 심었을 수 있는 현재 작업 디렉터리에서 확장명(as 또는 )을 먼저 gawk
로드하려고 시도합니다 . 와 함께 제공되는 확장 프로그램 의 경로는 시스템에 따라 다를 수 있습니다.inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
또는 perl
(어디 -i
에서 나온 것인지):
(export VAR
perl -pi -e '$_ .= "$ENV{VAR}\n" if /MatchingPattern/' somefile)
답변2
이 오류는 실제 뒤에 백슬래시가 필요한 sed
추가 명령 으로 인해 발생합니다 .a
a
GNU를 사용하면 sed
:
$ sed "/pattern/a\\$VAR" file.in >file.out
BSD sed
는 내가 아는 a
한 줄 바꿈이 제대로 이스케이프되지 않는 한 명령을 사용하여 파일에 한 줄만 삽입할 수 있습니다.
BSD로 이 문제를 해결하는 방법에 대한 밀접하게 관련된 답변은 다음과 같습니다 sed
.http://unix.stackexchange.com/a/60322