사용자의 입력을 받아들이고 모든 특수 문자를 "\" + 문자로 바꾸는 스크립트 "test.sh"를 작성하고 싶습니다. 내 스크립트:
#!/bin/bash
echo 'input='"$1"
arg=`echo "$1" | sed 's:[]\[\^\$\.\*\/]:\\&:g'`
echo 'modified input='"$arg"
내 명령은 특수 문자가 없는 문자열 "xy"에서 작동합니다. 터미널에서 다음 명령을 실행합니다.
test.sh xy
나는 얻다:
input=xy
modified input=xy
그러나 이것을 실행하면 다음과 같습니다.
test.sh x.y
나는 얻다:
input=x.y
modified input=x&y
이 스크립트가 왜 작동하지 않는지 이해할 수 없습니다. 나는 다음을 얻을 것으로 기대합니다:
input=x.y
modified input=x\.y
문제는 이 sed 명령에 있다고 생각하지만 어디에 있는지 잘 모르겠습니다.
sed 's:[]\[\^\$\.\*\/]:\\&:g'
답변1
그룹을 올바르게 캡처하지 않은 것 같습니다. 이 시도?
sed 's:\([]\[\^\$\.\*\/]\):\\\1:g'
편집: 신경 쓰지 마세요. &의 관련성을 모르겠습니다. 문제는 구문 분석 및 서브쉘 전달로 인해 대체에서 슬래시를 추가로 이스케이프 처리해야 한다는 것입니다.
sed 's:[]\[\^\$\.\*\/]:\\\\&:g'
또한 백틱 대신 $(command)를 사용하면 추가 \가 필요하지 않습니다.
답변2
따라서 작업은 문자열에 있는 sed
모든 특수 문자(내가 추가한 문자로 정의됨 )를 이스케이프하는 대체 문자를 작성하는 것입니다.[]^$.*/
\
대체품은 다음과 같습니다.
s/[][\^$.*/]/\\&/g
[...]
실제로 세트의 문자를 이스케이프할 필요는 없습니다 ( \
문자 그대로 처리되므로할 수 없다그곳에서 무엇이든 탈출하세요), 우리가 확인해야 할 유일한 것은 이것이 ]
바로 시작 부분에 있다는 것입니다.
따라서 스크립트(셸 함수로 다시 작성되거나 수정됨)는 다음과 같습니다.
function escape
{
printf '%s\n' "$1" | sed 's/[][\^$.*/]/\\&/g'
}
시험:
$ escape 'hello world'
hello world
$ escape '*.*'
\*\.\*
$ escape '\/'
\\\/
$ escape '/\'
\/\\
$ escape 's/[][\^$.*/]/\\&/g'
s\/\[\]\[\\\^\$\.\*\/\]\/\\\\&\/g