문제

내 배쉬 스크립트에는 외부 (사용자로부터 수신) 문자열이 있으며 SED 패턴으로 사용해야합니다.

REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"

어떻게 탈출 할 수 있습니까? $REPLACE 문자열은 안전하게 받아 들여질 수 있습니다 sed 문자 그대로 교체?

노트: 그만큼 KEYWORD 일치 등이없는 멍청한 서브 스트링입니다. 사용자가 제공하지 않습니다.

도움이 되었습니까?

해결책

경고: 이건 그렇습니다 ~ 아니다 Newlines를 고려하십시오. 더 심층적 인 대답은 참조하십시오 이 소위 대신에. (감사합니다, Ed Morton & Niklas Peter)

모든 것을 피하는 것은 나쁜 생각입니다. SED는 탈출해야 할 많은 캐릭터가 필요합니다 가져 오기 그들의 특별한 의미. 예를 들어, 교체 문자열에서 숫자를 탈출하면 역전으로 전환됩니다.

Ben Blank가 말했듯이, 교체 문자열에서 탈출 해야하는 3 개의 문자 만 있습니다 (자신의 탈출, 성명서의 끝을위한 슬래시 및 모두 교체) :

sed -e 's/[\/&]/\\&/g'

당신이 탈출해야한다면 KEYWORD 문자열, 다음은 필요한 것입니다.

sed -e 's/[]\/$*.^[]/\\&/g'

다른 캐릭터를 사용하는 경우 기억하십시오 / Delimiter로서 사용중인 문자 위의 표현식에서 슬래시를 교체해야합니다. 설명은 Peterjclaw의 의견을 참조하십시오.

편집 : 이전에 설명되지 않은 일부 코너 케이스로 인해 위의 명령은 여러 번 변경되었습니다. 자세한 내용은 편집 기록을 확인하십시오.

다른 팁

SED 명령을 사용하면 대신 다른 문자를 사용할 수 있습니다. / 분리기 :

sed 's#"http://www\.fubar\.com"#URL_FUBAR#g'

이중 인용문은 문제가되지 않습니다.

교체 절에서 특별히 취급되는 유일한 세 문자 문자는 다음과 같습니다. / (조항을 닫으려면), \ (캐릭터, 역전, & c.를 탈출하려면) & (교체에 일치를 포함시키기 위해). 따라서, 당신이해야 할 일은이 세 캐릭터를 피하기 만하면됩니다.

sed "s/KEYWORD/$(echo $REPLACE | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g')/g"

예시:

$ export REPLACE="'\"|\\/><&!"
$ echo fooKEYWORDbar | sed "s/KEYWORD/$(echo $REPLACE | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g')/g"
foo'"|\/><&!bar

피아노 사우루스의 정규 표현을 바탕으로 키워드와 교체를 모두 피하는 배쉬 기능을 만들었습니다.

function sedeasy {
  sed -i "s/$(echo $1 | sed -e 's/\([[\/.*]\|\]\)/\\&/g')/$(echo $2 | sed -e 's/[\/&]/\\&/g')/g" $3
}

사용 방법은 다음과 같습니다.

sedeasy "include /etc/nginx/conf.d/*" "include /apps/*/conf/nginx.conf" /etc/nginx/nginx.conf

응답하기에는 조금 늦었지만이 작업을 수행하는 훨씬 간단한 방법이 있습니다. 구분 기자 (즉, 필드를 분리하는 캐릭터)를 변경하십시오. 그래서 대신 s/foo/bar/ 당신은 쓰기 s|bar|foo.

그리고 여기에 쉬운 방법은 다음과 같습니다.

sed 's|/\*!50017 DEFINER=`snafu`@`localhost`\*/||g'

결과 출력에는 그 불쾌한 정의 조항이 없습니다.

당신이 잘못된 질문을하는 것이 밝혀졌습니다. 나는 또한 잘못된 질문을했다. 그것이 잘못된 이유는 첫 번째 문장의 시작입니다. "내에서 세게 때리다 스크립트...".

나는 같은 질문을했고 같은 실수를했다. Bash를 사용하는 경우 Sed를 사용할 필요가 없습니다. 많이 청정기 Bash에 내장 된 교체 기능을 사용하려면).

예를 들어 : 예를 들어 :

function escape-all-funny-characters() { UNKNOWN_CODE_THAT_ANSWERS_THE_QUESTION_YOU_ASKED; }
INPUT='some long string with KEYWORD that need replacing KEYWORD.'
A="$(escape-all-funny-characters 'KEYWORD')"
B="$(escape-all-funny-characters '<funny characters here>')"
OUTPUT="$(sed "s/$A/$B/g" <<<"$INPUT")"

Bash 기능을 독점적으로 사용할 수 있습니다.

INPUT='some long string with KEYWORD that need replacing KEYWORD.'
A='KEYWORD'
B='<funny characters here>'
OUTPUT="${INPUT//"$A"/"$B"}"

awk 사용 - 더 깨끗합니다.

$ awk -v R='//addr:\\file' '{ sub("THIS", R, $0); print $0 }' <<< "http://file:\_THIS_/path/to/a/file\\is\\\a\\ nightmare"
http://file:\_//addr:\file_/path/to/a/file\\is\\\a\\ nightmare

다음은 내가 얼마 전에 사용한 멍청한 예입니다. 새로운 멍청한 인쇄를 인쇄하는 것은 어색한 것입니다. Awk and Sed 비슷한 것은 좋은 템플릿 일 수 있습니다.

ls | awk '{ print "awk " "'"'"'"  " {print $1,$2,$3} " "'"'"'"  " " $1 ".old_ext > " $1 ".new_ext"  }' > for_the_birds

과도하게 보이지만 어떻게 든 인용문의 조합은 '인쇄 된'리터럴로 인쇄하는 데 작동합니다. 그런 다음 내가 정확하게 기억한다면 Vaiables는 다음과 같은 인용문으로 둘러싸여 있습니다 : "$ 1". 그것을 시도하고 SED와 어떻게 작동하는지 알려주세요.

나는 탭과 같은 특수 문자로 깨질 것입니다.

function sedeasy_improved {
    sed -i "s/$(
        echo "$1" | sed -e 's/\([[\/.*]\|\]\)/\\&/g' 
            | sed -e 's:\t:\\t:g'
    )/$(
        echo "$2" | sed -e 's/[\/&]/\\&/g' 
            | sed -e 's:\t:\\t:g'
    )/g" "$3"
}

그래서, 다른 것은 무엇입니까? $1 그리고 $2 쉘 확장을 피하고 탭 또는 이중 공간을 보존하기 위해 인용구로 싸여 있습니다.

추가 배관 | sed -e 's:\t:\\t:g' (좋아요 : 탭을 변환하는 토큰) \t.

"and '주변의 쉘 제한으로 발생하는 모든 즐거움을 잊지 마십시오.

So (KSH)

Var=">New version of \"content' here <"
printf "%s" "${Var}" | sed "s/[&\/\\\\*\\"']/\\&/g' | read -r EscVar

echo "Here is your \"text\" to change" | sed "s/text/${EscVar}/g"

사례가 전달할 임의의 암호를 생성하는 경우 sed 패턴을 교체 한 다음 임의 문자열의 문자 세트에주의를 기울 이도록 선택하십시오. Base64로 값을 인코딩하여 만들어진 비밀번호를 선택하면 Base64에서 가능하고 특수 문자 인 문자 만 있습니다. sed 패턴을 교체하십시오. 해당 문자는 "/"이며 생성하는 비밀번호에서 쉽게 제거됩니다.

# password 32 characters log, minus any copies of the "/" character.
pass=`openssl rand -base64 32 | sed -e 's/\///g'`;

SED 명령에서 변수 값을 바꾸려고하는 경우 예제를 제거하십시오.

sed -i 's/dev-/dev-$ENV/g' test to sed -i s/dev-/dev-$ENV/g test

이 작업을 수행하는 더 쉬운 방법은 단순히 문자열을 손에 구축하고 매개 변수로 사용하는 것입니다. sed

rpstring="s/KEYWORD/$REPLACE/g"
sed -i $rpstring  test.txt
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top