Perl `rename` 스크립트가 어떤 경우에는 작동하지 않습니까?

Perl `rename` 스크립트가 어떤 경우에는 작동하지 않습니까?

다음 명령을 실행해 보았습니다.

find . -type f -exec rename -v 's/ /_/g' {} \;

, 이름에 공백과 밑줄이 포함된 모든 파일의 이름을 반복적으로 바꿉니다. 문제는 작동할 때도 있고 작동하지 않을 때도 있다는 것입니다. 작동하지 않으면 다음 오류가 발생합니다.

Can't rename ./dir/subdir/file name with spaces ./dir/subdir/file_name_with_spaces: No such file or directory

내가 뭔가 잘못하고 있는 게 아닐까?

답변1

rename무슨 일이 일어나는가는 다음 파일에서 실행을 시도한다는 것입니다목차이름에 공백이 있습니다. 기본적으로 이 rename유틸리티는 주어진 Perl 코드 비트를 전체 인수, 즉 경로명의 파일 이름 부분뿐만 아니라 전체 경로 이름에 적용하므로 다소 단순합니다.

다행히 경로 이름의 파일 이름 부분으로 작업을 제한하는 것은 쉽습니다.

find . -type f -execdir rename -v 'tr/ /_/' -- {} \;

-execdir술어는 비표준이지만 일반적으로 구현됩니다. -execdir대신 in 을 사용하면 -exec파일이 발견된 디렉터리를 현재 디렉터리로 사용하여 명령이 실행됩니다. 이렇게 하면 rename유틸리티는 파일의 상위 디렉터리 이름을 볼 수 없습니다.

--여기서는 이름이 대시로 시작하는 파일의 이름을 바꾸려고 하는 이벤트를 방지하기 위해 이를 사용하고 있습니다 (참조"--"(이중 대시)은(는) 무슨 뜻인가요?). 파일 이름 앞에 접두사가 붙기 때문에 이는 GNU에서는 문제가 되지 않지만 find, 적어도 ./BSD 시스템의 일부 구현에서는 이런 일이 발생하지 않습니다.find

rename또 다른 옵션은 유틸리티의 -d, --filename또는 옵션(동일함)을 --nopath사용 하는 것입니다 .--nofullpath

find . -type f -exec rename -d -v 'tr/ /_/' {} +

이렇게 하면 유틸리티가 주어진 경로 이름 인수의 파일 이름 부분 이외의 다른 부분을 고려하지 못하게 됩니다.

s///나는 Perl 표현식을 명령에서 명령으로 자유롭게 변경할 수 있었습니다 tr///. 왜냐하면 우리가 수행하는 변환은 일반적인 대체가 아니라 단순한 음역이기 때문입니다.

rename공백이 포함된 파일 이름에만 실행하고 싶을 수도 있습니다 . 이는 2017년 1월 또는 그 이전 -name '* *'-exec테스트를 통해 선택되었습니다 -execdir.

관련 정보