sed 변수에는 /가 포함됩니다.

sed 변수에는 /가 포함됩니다.

다음과 같은 내용이 포함된 텍스트 파일이 있습니다.

some content  
replace content  
other content

다음과 같은 몇 가지 변수가 있습니다.

PATH="/path/to/scriptdir"
PARAMETERS="para1 para2"
FILETOCHANGE="/foo/bar"

이제 다음으로 시작하는 텍스트 파일의 내용을 바꾸고 싶습니다.바꾸다, 변수의 내용그리고매개변수. 교체 후 텍스트 파일은 다음과 같아야 합니다.

some content
/path/to/scriptdir/script para1 para2
other content

방금 몇 가지 sed 명령을 시도했지만 계속 오류가 발생합니다. 예를 들어

sed -i "s/^replace.*$/$PATH/script $PARAMETERS/g" $FILETOCHANGE
sed: -e expression #1, char 12: unknown option to `s'

또는

sed -i "s|^replace.*$|$PATH/script $PARAMETERS|g" $FILETOCHANGE
sed: -e expression #1, char 58: unterminated `s' command

내가 뭘 잘못했는지 말해줄 수 있나요?

답변1

(1) 하다아니요PATH이를 위해 변수를 사용하십시오. 껍질에는 특별한 의미가 있습니다. 저는 SCRIPTDIR여기서 선택합니다:

SCRIPTDIR="/path/to/scriptdir"
PARAMETERS="para1 para2"
FILETOCHANGE="/foo/bar"

/(2) sed의 대체 명령에는 슬래시( )가 필요하지 않습니다. s#this#that#그렇지 않으면 s|this|that|효과는 동일합니다 s/this/that/g. Sed는 s나머지 (대체) 명령에 대한 s구분 기호 로 뒤에 오는 문자만 사용합니다 . 이를 사용하면 패턴 및 대체 문자열의 슬래시 관련 문제를 피할 수 있습니다. |예를 들어 구분 기호로 사용할 때 슬래시는 sed에 특별한 의미가 없습니다.

따라서 다음과 같이 작동합니다.

sed "s%^replace.*$%$SCRIPTDIR/script $PARAMETERS%g" $FILETOCHANGE

답변2

최종 해결책은 sed에서 Perl로 전환하는 것이었습니다. Perl은 변수를 쉘처럼 매크로 확장이 아닌 일급 시민으로 취급합니다.

path=/path/to/scriptdir parameters="para1 para2" perl -i~ -pe \
    's|^replace.*$|$ENV{path}/script $ENV{parameters}|g' -- "$filetochange"
  • -p입력된 내용을 한 줄씩 읽고 처리 후 각 줄을 인쇄합니다.
  • 해시에는 %ENV명령 시작 부분에 할당된 환경 변수가 포함되어 있어 해당 변수를 명령으로 내보낼 수 있습니다.
  • s///(필요에 따라 구분 기호를 변경하십시오.) sed와 유사합니다.펠롭

관련 정보