[bash] 슬래시가 포함 된 변수를 sed에 전달하는 방법

슬래시를 포함하는 변수를 패턴으로 sed어떻게 전달 합니까?

예를 들어 다음 변수가있는 경우 :

var="/Users/Documents/name/file"

나는 그것을 다음과 sed같이 전달하고 싶다 .

sed "s/$var/replace/g" "$file"

그러나 오류가 발생합니다. 문제를 어떻게 피할 수 있습니까?



답변

sed모든 구분 기호 ( 제어 문자 포함) 를 사용할 수 있도록 대체 정규식 구분 기호 를 사용합니다 .

sed "s~$var~replace~g" $file


답변

순수한 bash 대답 : 매개 변수 확장 을 사용하여 변수의 슬래시를 백 슬래시로 이스케이프하십시오.

var="/Users/Documents/name/file"
sed "s/${var//\//\\/}/replace/g" $file


답변

이를 수행하는 또 다른 방법은 anubhava의 대답보다 추악하지만 var다른 sed명령 을 사용하여 모든 백 슬래시를 이스케이프하는 것입니다 .

var=$(echo "$var" | sed 's/\//\\\//g')

그러면 작동합니다.

sed "s/$var/replace/g" $file


답변

/in sed를 구분 기호로 사용 하면 대체 될 때 변수의 슬래시와 충돌하므로 오류가 발생합니다. 이를 피하는 한 가지 방법은 해당 변수에있는 모든 문자에서 고유 한 다른 구분 기호를 사용하는 것입니다.

var="/Users/Documents/name/file"

상황에 맞는 옥토 토프 캐릭터 (또는 /사용하기 쉽지 않은 다른 캐릭터 )를 사용할 수 있습니다.

sed "s#$var#replace#g" 

또는

sed 's#$'$var'#replace#g'

변수에 공백이 없을 때 적합합니다.

또는

sed 's#$"'$var'"#replace#g'

셸이 특수 셸 문자로 간주 될 수있는 모든 문자를 셸에 끼울 수있는 전체 명령을 큰 따옴표로 묶는 것과 비교할 때만 해당 변수에있는 모든 것을 대체하는 데 관심이 있으므로 위의 내용을 사용하는 것이 현명합니다.


답변

이것은 오래된 질문이지만 여기에 대한 답변 중 어느 것도 작업 s/from/to/에 대해 자세히 설명하지 않습니다.

sed진술 의 일반적인 형식은 다음과 같습니다 .

*address* *action*

여기서 address 는 정규식 범위 또는 줄 번호 범위 일 수 있습니다 (또는 비어있는 경우 작업 이 모든 입력 줄에 적용됨). 예를 들어

sed '1,4d' file

라인 1부터 4까지 삭제합니다 ( 주소 는 라인 번호 범위 1,4이고 작업d삭제 명령입니다). 과

sed '/ick/,$s/foo/bar/' file

처음 나타나는 대체 할 foo과이 bar정규 표현식에 제 매치 라인 사이에 ick파일 끝에합니다 ( 어드레스 범위 인 /ick/,$상기 액션 은 IS s대체 명령 s/foo/bar/).

이 컨텍스트 ick에서 변수에서 온 경우 다음을 수행 할 수 있습니다.

sed "/$variable/,\$s/foo/bar/"

(단일 대신 큰 따옴표를 사용하여 쉘이 변수를 보간 할 수 있고 큰 따옴표 안에 리터럴 달러 기호를 따옴표로 묶어야 함) 변수에 슬래시가 포함되어 있으면 구문 오류가 발생합니다. (쉘은 변수를 확장 한 다음 결과 문자열을에 전달합니다 sed. 따라서 sed리터럴 텍스트 만 볼 수 있습니다. 쉘의 변수에 대한 개념이 없습니다.)

해결 방법은 다른 구분 기호를 사용하는 것입니다 (분명히 변수 값에 나타날 수없는 문자를 사용할 수 있어야하는 경우). 그러나 s%foo%bar%경우 와 달리 다른 구분 기호를 사용하려면 구분 기호 앞에 백 슬래시가 필요합니다. 기본값보다 구분 기호 /:

sed "\\%$variable%,\$s/foo/bar/" file

(작은 따옴표 안에는 백 슬래시 하나로 충분합니다.) 또는 값의 모든 슬래시를 개별적으로 이스케이프 할 수 있습니다. 이 특정 구문은 Bash 전용입니다.

sed "/${variable//\//\\/}/,\$s/foo/bar/" file

또는 다른 셸을 사용하는 경우

escaped=$(echo "$variable" | sed 's%/%\\/%g')
sed "s/$escaped/,\$s/foo/bar/" file

명확성을 $variable위해 문자열 이 포함 된 경우 1/2위 명령은 다음과 같습니다.

sed '\%1/2%,$s/foo/bar/' file

첫 번째 경우에는

sed '/1\/2/,$s/foo/bar/' file

두 번째.


답변

Perl을 사용하십시오. 여기서 변수는 확장 매크로가 아니라 일급 시민입니다.

var=/Users/Documents/name/file perl -pe 's/\Q$ENV{var}/replace/g' $file
  • -p 입력 한 줄을 한 줄씩 읽고 처리 후 줄을 인쇄합니다.
  • \Q다음 문자열의 모든 메타 문자를 따옴표로 묶습니다 (여기에 제시된 값에는 필요하지 않지만 값에 포함 된 경우 필요 [하거나 정규 표현식에 특수한 다른 값).

답변