내 bash 스크립트에는 sed 패턴으로 사용해야하는 외부 (사용자로부터받은) 문자열이 있습니다.
REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"
$REPLACE
문자열을 이스케이프 처리하여 sed
문자 그대로 대체 할 수 있습니까?
참고 : (가) KEYWORD
없는 경기 등 그것은 사용자가 제공되지와 바보 같은 문자열입니다.
답변
경고 : 이것은 개행을 고려 하지 않습니다 . 더 자세한 답변은 이 SO 질문을 참조하십시오 . (감사합니다, Ed Morton & Niklas Peter)
모든 것을 탈출하는 것은 나쁜 생각입니다. Sed는 특별한 의미 를 얻기 위해 많은 캐릭터를 탈출해야 합니다. 예를 들어, 대체 문자열에서 숫자를 이스케이프하면 역 참조로 바뀝니다.
Ben Blank가 말했듯이 대체 문자열에서 이스케이프해야 할 문자는 세 개뿐입니다 (이스케이프, 명령문 끝 및 슬래시 모두 슬래시).
ESCAPED_REPLACE=$(printf '%s\n' "$REPLACE" | sed -e 's/[\/&]/\\&/g')
# Now you can use ESCAPED_REPLACE in the original sed statement
sed "s/KEYWORD/$ESCAPED_REPLACE/g"
KEYWORD
문자열 을 이스케이프해야하는 경우 다음이 필요합니다.
sed -e 's/[]\/$*.^[]/\\&/g'
그리고 다음에 의해 사용될 수 있습니다 :
KEYWORD="The Keyword You Need";
ESCAPED_KEYWORD=$(printf '%s\n' "$KEYWORD" | sed -e 's/[]\/$*.^[]/\\&/g');
# Now you can use it inside the original sed statement to replace text
sed "s/$ESCAPED_KEYWORD/$ESCAPED_REPLACE/g"
/
분리 문자 이외의 문자를 사용하는 경우 사용중인 문자 와 함께 위의 표현식에서 슬래시를 바꿔야합니다. 설명은 PeterJCLaw의 의견을 참조하십시오.
편집 : 이전에 설명되지 않은 일부 경우로 인해 위의 명령이 여러 번 변경되었습니다. 자세한 내용은 편집 기록을 확인하십시오.
답변
sed 명령을 사용하면 /
구분 기호 대신 다른 문자를 사용할 수 있습니다 .
sed 's#"http://www\.fubar\.com"#URL_FUBAR#g'
큰 따옴표는 문제가되지 않습니다.
답변
replace 절에서 특별히 처리되는 세 가지 리터럴 문자는 /
( 구문 닫기), \
(이스케이프 문자, 역 참조 등) 및 &
(대체에 일치 항목 포함)입니다. 따라서이 세 문자를 피하기 만하면됩니다.
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
답변
피아노 사우루스의 정규 표현식을 기반으로 키워드와 대체를 모두 피하는 bash 함수를 만들었습니다.
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'
결과 출력에는 불쾌한 DEFINER 절이 없습니다.
답변
당신이 잘못된 질문을하고있는 것으로 나타났습니다. 나는 또한 잘못된 질문을했다. 그것이 틀린 이유는 첫 문장의 시작입니다 : “내 bash 스크립트에서 …”.
나는 같은 질문을했고 같은 실수를했다. bash를 사용하는 경우 sed를 사용하여 문자열을 교체 할 필요가 없습니다 ( bash에 내장 된 replace 기능을 사용하는 것이 훨씬 깨끗합니다).
예를 들어,
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")"
배쉬 기능을 독점적으로 사용할 수 있습니다 :
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