하위 디렉터리 작업을 위해 이 찾기 및 이름 바꾸기 명령을 어떻게 사용할 수 있습니까? [복사]

하위 디렉터리 작업을 위해 이 찾기 및 이름 바꾸기 명령을 어떻게 사용할 수 있습니까? [복사]

중복 가능성:
파일 및 디렉터리의 이름을 반복적으로 바꿉니다.

나는 파일과 디렉터리가 변경되면서 자주 변경되는 대규모 음악 파일 디렉터리를 가지고 있습니다. 저는 파일과 디렉터리 이름에 공백이 포함되지 않도록 하는 것을 선호하므로 모두 밑줄로 바꿉니다.

홈 디렉터리로 이동하여 다음 명령을 실행합니다.

$ find -type d -exec rename 'y/\ /\_/' {} \;

문제는 하위 디렉터리가 있을 때 이 명령이 손실된 것처럼 보이고 오류를 반환한다는 것입니다. 따라서 다음과 같은 디렉토리 구조가 있는 경우:

여기에 이미지 설명을 입력하세요.

...명령을 실행하면 다음 오류가 발생합니다.

$ find -type d -exec rename 'y/\ /\_/' {} \;
find: `./Test 02': No such file or directory
find: `./Test 01': No such file or directory
find: `./Test 03': No such file or directory

결과적으로 내 디렉토리 구조는 다음과 같습니다. 하위 디렉터리에는 여전히 공백이 있습니다.

여기에 이미지 설명을 입력하세요.

명령을 다시 실행하면 문제의 디렉터리 이름이 변경된 것처럼 보이지만 다음과 같은 오류가 발생합니다.

$ find -type d -exec rename 'y/\ /\_/' {} \;
find: `./Test_01/Test A': No such file or directory
find: `./Test_01/Test C': No such file or directory
find: `./Test_01/Test B': No such file or directory

마지막으로 명령을 다시 실행했는데 오류가 발생하지 않았으며 모든 디렉터리와 하위 디렉터리의 이름이 원하는 대로 지정되었습니다.

여기에 이미지 설명을 입력하세요.

분명히 이렇게 하려면 하위 디렉터리가 여러 개 있을 때 명령을 더 많이 실행해야 하므로 지루해질 수 있습니다.

이 명령을 한 번만 실행하면 모든 디렉터리와 하위 디렉터리의 이름이 한꺼번에 바뀌도록 하려면 어떻게 해야 합니까?

나의 궁극적인 목표는 이를 Bash 스크립트에 포함시켜 다른 유사한 관리 명령과 함께 실행할 수 있도록 하는 것입니다. 따라서 오류를 반환하지 않거나 추가 입력을 요구하지 않도록 해야 합니다. 또한 중요한 경우 Ubuntu 12.04를 실행하고 있습니다.

답변1

일어나는 일은 다음과 같습니다.

  • find일치하는 디렉터리를 찾았습니다 ./Test 02.
  • findrename이 디렉터리에서 명령을 실행합니다.
  • renameTest 02로 이름이 변경되었습니다 Test_02.
  • find디렉토리로 내려가 보십시오 Test 02. 그러나 더 이상 존재하지 않습니다.

이 문제를 해결하는 가장 쉬운 방법은 find다른 방법으로 작업하도록 지시하는 것입니다. 먼저 디렉터리 내에서 일치하는 항목을 찾은 다음 디렉터리 자체에서 일치하는 항목을 확인합니다. 이것이 바로 이 -depth옵션의 역할입니다.

을 추가하면 -depth또 다른 문제가 발생합니다. 즉, 을 호출 find하면 디렉터리 이름을 로 바꾸려고 시도한다는 것입니다 . 라는 디렉터리가 없기 때문에 이 작업은 실패합니다 . 간단한 해결 방법은 디렉터리 내부에서 호출되고 인수 로 전달되는 옵션을 사용하는 것입니다 . 명령을 종료하는 대신 를 사용하여 한 배치에 여러 인수를 전달하면 작업 속도를 높일 수 있습니다 .Test 01/Test Arename 'y/\ /\_/' 'Test 01/Test A'Test_01/Test_ATest_01-execdirrenameTest 01Test Arename+;-execdir

find -depth -name '* *' -type d -execdir rename 'y/ /_/' {} +

또는 다음 짧지만 신비한 zsh 명령을 사용하세요.

autoload zmv
zmv -Qw '**/*(/D)' '$1${2// /_}'

이것zmv기능패턴에 따라 파일 이름을 바꿉니다. 소스 패턴은 **/*모든 하위 디렉터리( )( )의 모든 파일을 재귀적으로 일치시키는 것입니다. 이것***/글로벌 예선(옵션으로 활성화됨 -Q)은 디렉터리( /)만 일치하고 도트 파일( D)을 포함한다는 의미입니다. 이 -w옵션은 소스 패턴의 각 와일드카드 문자에 대한 역참조를 생성합니다. 교체는 첫 번째 와일드카드 문자( 의 경우 마지막 문자 포함 ) $1를 지정하는 일치 항목으로 시작한 다음 모든 공백 문자를 로 바꾸도록 해당 항목 (일치하는 내용 )을 수정합니다 . 명령이 수행하는 작업을 확인하는 옵션을 추가하면 다음과 같이 먼저 깊이를 탐색하는 것을 확인할 수 있습니다 .**/${2// /_}$2*_-vfind -depth

관련 정보