(여기 에서 각각) s명령 의 왼쪽과 오른쪽에 사용되는 변수를 이스케이프하려면 다음을 수행하십시오.sed$lhs$rhs
escaped_lhs=$(printf '%s\n' "$lhs" | sed 's:[][\/.^$*]:\\&:g')
escaped_rhs=$(printf '%s\n' "$rhs" | sed 's:[\/&]:\\&:g;$!s/$/\\/')
sed "s/$escaped_lhs/$escaped_rhs/"
참고 $lhs개행 문자를 포함 할 수 없습니다.
즉, LHS에서 모든 정규 표현식 연산자 ( ][.^$*), 이스케이프 문자 자체 ( \) 및 구분 기호 ( /)를 이스케이프 처리 하십시오 .
RHS에서는, &구분 기호, 백 슬래시 및 줄 바꿈 문자 만 이스케이프하면됩니다 (마지막 줄을 제외한 각 줄 끝에 백 슬래시를 삽입하여 수행함 $!s/$/\\/).
그것은 당신이 사용하는 가정 /당신의 구분자로 sed s명령 및 사용하지 않는 것이 확장 된 RE 와 -r(GNU는 sed/ ssed/ ast/ busybox sed) 또는 -E(BSD의, ast최근 GNU, 최근 비지 박스) 또는 PCREs 와 -R( ssed) 또는 증강 된 RE 와 -A/ -X( ast)한다 모두 추가 RE 연산자가 있습니다.
임의의 데이터를 처리 할 때 몇 가지 기본 규칙 :
- 사용하지 마십시오
echo
- 변수를 인용하십시오
- 로케일의 영향을 고려하십시오 (특히 문자 세트 : 이스케이프
sed 명령은 이스케이프 된 문자열을 sed사용하는 명령 과 동일한 로케일 (및 동일한 명령 사용) 과 같은 로케일에서 실행되는 것이 중요 합니다)sed
- 개행 문자를 잊지 마십시오 (여기에서
$lhs포함 여부를 확인 하고 조치를 취할 수 있음).
또 다른 옵션은 환경에서 문자열 perl대신 사용 sed하고 문자열을 전달하고 문자 그대로 문자열을 가져 오기 위해 \Q/ \E perlregexp 연산자를 사용하는 것입니다 .
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl(기본적으로)는 로케일의 문자 집합에 영향을받지 않으며, 위의 경우 사용자에게 어떤 문자 (있는 경우)를 신경 쓰지 않고 문자열을 바이트 배열로 간주합니다. 를 사용하면 모든 명령에 대해 sed로케일을 C로 고정하여 동일한 결과를 얻을 수 있습니다 (오류 메시지의 언어에도 영향을 미칩니다).LC_ALL=Csed