sed 특수 문자 대체가 쉘 스크립트에서 작동하지 않습니다

sed 특수 문자 대체가 쉘 스크립트에서 작동하지 않습니다

사용자의 입력을 받아들이고 모든 특수 문자를 "\" + 문자로 바꾸는 스크립트 "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

관련 정보