나는 awk '{ gsub(/BAR|WIBBLE/, "FOO"); print }'
다음과 같은 데이터의 텍스트를 바꾸는 데 사용합니다.
SOMETHING [BAR, WIBBLE]
SOMETHING [BAR]
그러면 원하는 결과가 제공됩니다.
SOMETHING [FOO, FOO]
SOMETHING [FOO]
하지만 이제 교체해야 할 텍스트를 다음과 같이 업데이트해야 합니다.
awk '{ gsub(/BAR|WIBBLE|ME/, "FOO"); print }'
그러면 텍스트가 다음과 같이 변경됩니다.
SOMETHING [ME, WIBBLE]
입력하다:
SOFOOTHING [FOO, FOO]
대괄호 사이의 텍스트로만 대체를 제한하려면 어떻게 해야 합니까(즉, 해당 텍스트를 유지합니까 SOMETHING
?)
편집하다
또한 강력한 텍스트가 필요합니다 SOMETHING
(예: SHE GAVE ME THAT
교체해서는 안 됨 ME
).
답변1
반드시 그럴까요 awk
? 대체의 대체 부분이 함수 호출일 수 있는 다른 언어에서는 훨씬 쉽습니다. 예를 들어 perl
:
perl -pe 'sub c{$s=shift;$s=~s/BAR|WIBBLE|ME/FOO/g;$s}s/\[.*?\]/c$&/ge'
답변2
GNU awk를 사용하면 대괄호의 내용을 설정한 다음 (일치하는 레코드 구분 기호)에서 대체를 수행할 수 있습니다 RS
.RT
awk -v RS='\\[[^]]*\\]' '{ gsub(/\<(BAR|WIBBLE|ME)\>/, "FOO", RT); printf "%s%s", $0, RT }' infile
입력 파일:
cat << EOF > infile
SHE GAVE ME THAT
SOMETHING [ME, WIBBLE, SOMMER]
EOF
산출:
SHE GAVE ME THAT
SOMETHING [FOO, FOO, SOMMER]
답변3
awk에는 정규식 대체 시 역참조가 부족하므로 상황에 따라 쉽게 대체할 수 없습니다. sed는 다음을 수행할 수 있습니다.
sed -e 's/\(\[[^]]*\)BAR/\1FOO/' 's/\(\[[^]]*\)ME/\1FOO/'
sed가 정규 표현식의 대체를 지원하는 경우:
sed -e 's/\(\[[^]]*\)\(BAR\|ME\)/\1FOO/'
접미사가 있어도 닫히지 않은 대괄호의 가장 긴 순서가 일치하므로 g
각 대괄호 쌍 내에서 단일 대체만 처리합니다 . [^]]*
이들 모두를 바꾸려면 명시적 루프를 사용하십시오. 이는 or 의 하위 문자열 FOO
이 아닌 경우에만 작동합니다 .BAR
ME
sed -e ': a' -e 's/\(\[[^]]*\)BAR/\1FOO/' -e 't a' \
-e 's/\(\[[^]]*\)ME/\1FOO/' -e 't a'
좀 더 복잡한 것이 필요하다면,펄을 사용하여.
답변4
awk '{ gsub(/\bBAR\b|\bWIBBLE\b|\bME\b/, "FOO"); print }'