현재 작업 디렉터리의 모든 파일에 사용된 용어를 바꾸려면 다음 명령을 실행합니다.
$ find . -type f -print0 | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'
이는 단어 대체를 수행하지만 .bup
해당 문자열이 포함된 파일이 전혀 포함되지 않은 파일 도 생성합니다 Ms. Johnson
.
불필요한 백업을 모두 생성하지 않고 교체를 수행하려면 어떻게 해야 합니까?
답변1
-exec
Find에는 임의의 명령을 수행하는 연산자가 있습니다 . 더 좋은 점 -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'
-r
null로 끝나는 이름
-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