Find -exec를 사용하여 grep 내용을 사용하여 파일 이름을 바꿉니다.

Find -exec를 사용하여 grep 내용을 사용하여 파일 이름을 바꿉니다.

find를 사용하여 파일 목록을 가져온 다음 pdfgrep을 사용하여 파일에서 문자열을 가져온 다음 해당 문자열을 사용하여 파일 이름을 바꾸려고 합니다.

분해 명령은 다음과 같습니다.

find . -name "*PayrollSelfBill_42652301*" -exec pdfgrep {}  -o -e "42652301-.{10}"

find는 내가 관심 있는 파일을 가져오고 -exec 부분의 pdfgrep은 올바른 문자열을 추출합니다.

{}에 저장된 파일을 pdfgrep의 출력으로 변환하고 싶습니다.

변수($()/backticks 사용)와 여러 -execs를 만들어 보았지만 아무 것도 작동하지 않는 것 같습니다.

누구든지 우아한 해결책을 가지고 있습니까?

답변1

단일 파일의 경우 $filename내가 올바르게 이해했다면 다음과 같은 작업을 수행하고 싶을 것입니다.

mv -i "$filename" "$( pdfgrep "$filename" -o -e "42652301-.{10}" )"

... $filename현재 디렉토리의 파일 이름으로 가정됩니다. 옳은? 그렇지 않은 경우 아래 코드도 잘못된 것입니다.

find좋습니다. 다음을 연결해 보겠습니다 -execdir.

find . -type f -name "*PayrollSelfBill_42652301*" -execdir sh -c '
    filename=$1
    mv -i "$filename" "$( pdfgrep "$filename" -o -e "42652301-.{10}" )"' sh {} ';'

그러면 관심 있는 파일을 찾고 스크립트 조각이 실행됩니다.파일이 발견된 디렉토리와 동일한 디렉토리(이것이 -execdir와 의 차이 입니다 -exec.)

가능한

find . -type f -name "*PayrollSelfBill_42652301*" \
    -execdir mv -i {} "$( pdfgrep {} -o -e "42652301-.{10}" )" ';'

실제로 서브쉘을 추가하지 않고도 작동합니다... 이제 생각해보면요. 그러나 나는 -execdir이것이 이기 때문에 서브쉘을 호출하는 것이 더 안전할 것이라고 생각합니다 find.


$pathname발견된 파일 중 하나라고 가정 하지만,아니요현재 디렉토리에서 다음은 파일에 대해 동일한 작업을 수행합니다.

mv -i "$pathname" "${pathname%/*}/$( pdfgrep "$pathname" -o -e "42652301-.{10}" )"

여기에서 ${pathname%/*}찾은 파일의 디렉터리로 확장합니다( 와 동일 $( dirname "$pathname" )).

이것은 효과가 있을 수 있습니다

find . -type f -name "*PayrollSelfBill_42652301*" \
    -exec  mv -i {} "$( dirname {} )/$( pdfgrep {} -o -e "42652301-.{10}" )" ';'

하지만 더 효율적으로 이를 사용하여 -exec ... {} +여러 파일을 일괄 처리할 수 있습니다.

find . -type f -name "*PayrollSelfBill_42652301*" -exec sh -c '
    for pathname do
        mv -i "$pathname" "${pathname%/*}/$( pdfgrep "$pathname" -o -e "42652301-.{10}" )"
    done' sh {} +

위 솔루션과의 차이점은 단 -execdir하나(또는 극소수)의 스크립트만 실행되고 더 빠른 대체 항목으로 대체되므로 이전 변형보다 잠재적으로 더 빨라진다는 것입니다. sh -cdirname

이 답변의 두 가지 변형과 관련됩니다.

관련 정보