sed 전체 교체를 수행하여 변경된 파일만 백업하려면 어떻게 해야 합니까?

sed 전체 교체를 수행하여 변경된 파일만 백업하려면 어떻게 해야 합니까?

현재 작업 디렉터리의 모든 파일에 사용된 용어를 바꾸려면 다음 명령을 실행합니다.

$ find . -type f -print0 | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

이는 단어 대체를 수행하지만 .bup해당 문자열이 포함된 파일이 전혀 포함되지 않은 파일 도 생성합니다 Ms. Johnson.

불필요한 백업을 모두 생성하지 않고 교체를 수행하려면 어떻게 해야 합니까?

답변1

-execFind에는 임의의 명령을 수행하는 연산자가 있습니다 . 더 좋은 점 -exec시험, 여러 명령을 함께 연결할 수 -exec있으며 이전 명령이 실패하면 이후 명령이 실행되지 않습니다. 이 문자열은 {}현재 파일 이름으로 바뀌고 ;명령의 끝을 표시합니다. 쉘 간섭을 방지하려면 두 가지를 모두 인용해야 합니다.

그래서:

find . -type f \
    -exec grep -q 'Ms. Johnson' '{}' \; \
    -exec sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g' '{}' \;

답변2

파일 내용을 확인하여 sed파일 작업 시 교체가 발생하는지 확인할 수 있습니다.

find . \
    -type f \
    -exec grep -q 'Ms. Johnson' {} \; \
    -print0 |
xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

정말 영리해지고 싶다면 find다음을 완전히 사용하지 않아도 됩니다.

grep -Z -l -r 'Ms. Johnson' |
    xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

답변3

매뉴얼 페이지를 보았지만 이를 수행할 수 있는 직접적인 방법을 찾지 못했습니다 sed. 여러분이 질문하기 전에 그랬을 것이라고 확신합니다. grep을 사용하여 이 문제를 해결하는 여러 가지 방법을 보았지만 가장 간단한 방법은 다음과 같습니다.

grep -rlZ "Ms. Johnson" . | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

-rnull로 끝나는 이름
-l만 사용하여 파일 이름을 반복적으로 인쇄합니다.
-Z

답변4

먼저 검색어와 일치하는 파일 목록을 작성해야 할 것 같습니다.

search="test"
for match in $(find -type f -exec grep -l $search "{}" \;)
do sed -i'.bup' -e "/$search/ s/$search/Mrs. Melbin/g" "$match"
done

관련 정보