한 명령에서 다른 명령으로 결과를 전송할 때 bash에서 공백 처리

한 명령에서 다른 명령으로 결과를 전송할 때 bash에서 공백 처리

여러 디렉터리/파일을 반복적으로 반복해야 하며, bash파일에 특정 문자열이 있으면 다른 문자열로 바꿔야 합니다. 내 스크립트에서 다음 줄을 사용하여 이 문제를 해결했습니다.

grep -rl "stringToReplace" * | xargs sed -ie 's/stringToReplace/newString/'

일부 파일의 이름에 공백이 있다는 것을 알기 전까지는 말이죠. 따라서 이라는 파일이 있는 경우 "dir1/dir2/I Am A File.txt"sed 에 4개 파일 ( , 및 ) xargs을 공급해 보십시오 ."dir1/dir2/I""Am""A""File.txt"

이 문제를 해결하기 위해 제가 생각할 수 있는 모든 방법을 시도했지만 여전히 작동하지 않습니다. 누구든지 아이디어가 있나요?

답변1

grep | xargs복잡한 파일 이름을 안전하게 처리할 수 없기 때문에 이런 종류의 작업에 가장 적합한 도구는 아닙니다. 그러나 파일 이름에 개행 문자가 포함되어 있지 않은 경우 몇 가지 옵션이 있습니다.

grep -rl "stringToReplace" * | xargs -I {} sed -ie 's/stringToReplace/newString/' {}

이는 다음에 적용됩니다.모든(XSI) POSIX 규격xargs. -I {}한 줄 처리를 강제하고 {}인수에 있는 경우 파일 이름을 바꿉니다.

GNU grep을 사용하면 다음을 사용할 수 있습니다.

grep -rl "stringToReplace" * | xargs -d '\n' sed -ie 's/stringToReplace/newString/'

이는 구분 기호로 공백 대신 개행 문자를 명시적으로 사용하지만 이식할 수 없는 확장입니다.

개행 문자가 포함된 둔한 파일 이름을 포함하여 가능한 모든 파일 이름을 존중하는 것이 더 안전합니다.이 POSIX find명령:

find . -type f -exec grep -q "stringToReplace" {} \; -exec sed -ie 's/stringToReplace/newString/' {} +

많은 greps를 생성합니다. 첫 번째는 -exec현재 디렉터리에서 발견된 각 일반 파일에 대해 한 번 실행되고, 두 번째는 첫 번째가 성공을 반환하는 파일 그룹에서만 실행됩니다(즉, grep파일에서 패턴이 발견된 위치). . 추가 프로세스는 현재 수행 중인 작업에 큰 문제가 아닐 수 있지만 특정 파일 시스템에 작은 파일이 많이 있는 경우 지배적일 수 있습니다.

더 안전하지만 이식성이 떨어지는 -execdirGNU 및 BSD의 주요 버전은 find기본적으로 동일한 작업을 수행하지만 특정 이름 변경 공격으로부터 보호합니다.

관련 정보