파일에서 매우 긴 문자열을 재귀적으로 교체

파일에서 매우 긴 문자열을 재귀적으로 교체

여러 파일에 매우 길고 복잡한 문자열이 있는데 이를 재귀적으로 제거/교체하고 싶습니다. 문자열에는 많은 슬래시, 백슬래시, 공백은 물론 모든 종류의 특수 기호가 포함되어 있습니다. 어떻게 해야 하나요? 간단한 find + sed 조합은 작동하지 않습니다. 왜냐하면 모든 특수 기호 때문에 거의 이스케이프할 수 없기 때문입니다.

파일에 검색 문자열을 쓰고 이를 검색 및 바꾸기 명령의 입력으로 사용할 수 있습니까?

답변1

문자열에는 개행 문자와 널 바이트를 제외한 모든 문자가 포함될 수 있다고 가정합니다. sed 패턴으로 사용하기 위해 이 문자열을 인용할 수 있습니다. 이러한 문자 $*./[\^앞에는 백슬래시가 와야 합니다. 대체 텍스트에서는 문자를 인용해야 합니다 \&/.

regexp=$(printf %s "$old" | sed 's:[$*./\[^]:\\&:g')
replacement=$(printf %s "$new" | sed 's:[\&/]:\\&:g')
sed -e "s/$regexp/$replacement/g"

Perl이 있다면 훨씬 더 간단합니다.

export old new
perl -pe 's/\Q$ENV{old}/$ENV{new}/'

현재 디렉터리와 하위 디렉터리의 모든 파일에 대해 반복적으로 작동합니다.

regexp=$(printf %s "$old" | sed 's:[$*./\[^]:\\&:g')
replacement=$(printf %s "$new" | sed 's:[\&/]:\\&:g')
export regexp replacement
find . -type f -exec sh -c 'for x; do sed -e "s/$regexp/$replacement/g" <"$x" >"$x.new" && mv "$x.new" "$x"; done' _ {} +

또는

export old new
find . -type f -exec perl -i -pe 's/\Q$ENV{old}/$ENV{new}/' {} +

답변2

-f예, 해당 옵션을 사용하여 [list] 표현식이 포함된 파일을 지정할 수 있어야 합니다.

   -f script-file, --file=script-file

          add the contents of script-file to the commands to be executed

그러나 여전히 특수 문자를 이스케이프해야 합니다(내가 아는 한 grep과 동등한 sed는 없습니다 ). 시스템에 Perl이 있는 경우 Perl을 사용하고 인용된 문자열 수정자를 --fixed-strings사용하는 것이 좋습니다 .\Q...\E

관련 정보