(여기 에서 각각) 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
perl
regexp 연산자를 사용하는 것입니다 .
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl
(기본적으로)는 로케일의 문자 집합에 영향을받지 않으며, 위의 경우 사용자에게 어떤 문자 (있는 경우)를 신경 쓰지 않고 문자열을 바이트 배열로 간주합니다. 를 사용하면 모든 명령에 대해 sed
로케일을 C
로 고정하여 동일한 결과를 얻을 수 있습니다 (오류 메시지의 언어에도 영향을 미칩니다).LC_ALL=C
sed