sed가 종료되지 않은 "s"에 대한 오류를 표시하는 이유는 무엇입니까?

sed가 종료되지 않은 "s"에 대한 오류를 표시하는 이유는 무엇입니까?

Bash 스크립트에 sed 대체 세트가 있는데 종료되지 않은 "s" 명령에 대한 오류가 발생합니다. sed 라인은 다음과 같습니다:

sed -n -e "s/TMPFOO1/$FOO1/" -e "s/TMPFOO2/$FOO2/" -e "s/TMPFOO3/$FOO3/" -e "s/TMPFOO4/$FOO4/" -e "s/TMPFOO5/$FOO5/" /home/foo/template > /home/foo/template/finishedresult

하지만 어떤 이유로 bash는 이것을 좋아하지 않으며 오류가 발생합니다.

sed: -e expression #4, char 69: unterminated `s' command

내가 여기서 무엇을 놓치고 있는 걸까요? SED 입력 변수를 만드는 방법은 무엇입니까? 제 생각에는 모두 종료되었습니다.

답변1

대체는 sed가 아닌 셸에서 수행되므로 sed 명령에 변수를 안전하게 삽입할 수 없습니다. 변수의 값은 sed 구문이 됩니다. 예를 들어 에서 개행 문자가 포함 "s/TMPFOO1/$FOO1/"되면 $FOO1관찰한 것과 유사한 구문 오류가 발생합니다. $FOO1a 가 포함 되면 명령이 /종료 s되고 오류가 발생하거나 다른 명령이 실행될 수 있습니다(다음 내용이 /유효한 sed 구문인 경우).

FOO1sed 명령에 포함하기 위해 특수 문자를 인용하기 위해 첫 번째 대체 패스를 수행할 수 있지만 awk를 사용하는 것이 훨씬 간단합니다. awk에는 변수의 개념과 변수의 초기값을 설정하는 명령줄 구문이 있습니다.

awk -v FOO1="$FOO1" -v FOO2="$FOO2" -v FOO3="$FOO3" -v FOO4="$FOO4" -v FOO5="$FOO5" '{
    sub(/TMPFOO1/, FOO1);
    sub(/TMPFOO2/, FOO2);
    sub(/TMPFOO3/, FOO3);
    sub(/TMPFOO4/, FOO4);
    sub(/TMPFOO5/, FOO5);
    print;
}' /home/foo/template > /home/foo/template/finishedresult

답변2

변수 중 하나에 $FOO에서 해석하는 특수 문자가 포함되어 있을 가능성이 높습니다 sed.

다른 오류 메시지를 생성하는 다른 버전이 있지만 sed다음은 비슷한 문제의 예입니다.

$ VAR=a
$ echo i | sed -e "s/i/"$VAR"/"
a
$ tmp> VAR=/
$ echo i | sed -e "s/i/"$VAR"/"
sed: 1: "s/i///
": bad flag in substitute command: '/'

이 경우 후행 슬래시 $VAR로 해석되는 문자가 포함됩니다 .sed

답변3

다른 사람들이 여기서 언급했듯이 FOO* 변수의 내용에 따라 달라집니다. 귀하의 경우에는 sed일부 특수 문자가 포함될 수 있으므로 사용은 잘못된 선택입니다.

보세요이 링크그리고 기능을 보세요gsub_literal

stdin에서 읽고 stdout에 쓰기 때문에 gsub_literal사용법은 다음과 같습니다.

gsub_literal "$search" "$replace" < /home/foo/template > /home/foo/template/finishedresult

예제 출력:

rany$ cat > foo.txt
a'
a'

rany$ gsub_literal a\' b < foo.txt 
b
b

답변4

명령에 백슬래시를 추가하면 문제가 해결되었습니다 sed 's/.../.../g'. 이 명령

sed 's/\"a/ä/g' input_file

나에게 이런 오류 메시지를 줬어

sed: -e 표현식 #1, 문자 9: 종료되지 않은 's' 명령

c-shell 스크립트의 일부로 실행되면 최신 버전에 대해서만 이 작업이 수행되고 sed이전 버전에는 수행되지 않습니다. (이상하게도 tc-shell의 명령줄에서 동일한 명령을 입력하면 제대로 작동합니다.)

c-shell 스크립트의 문제는 문자 앞에 백슬래시를 추가하여 해결되었습니다 ä.

sed 's/\"a/\ä/g' input_file

관련 정보