모든 디렉터리에 대해 - 접두사를 사용하여 모든 하위 디렉터리의 이름을 바꿉니다.

모든 디렉터리에 대해 - 접두사를 사용하여 모든 하위 디렉터리의 이름을 바꿉니다.

현재 2000개의 사용자 디렉터리가 있고 각 디렉터리에는 하위 디렉터리가 있습니다.

사용자_1

---> 하위 1

---> 어린이 2

사용자_29

---> 아이37

---> 어린이 56

모든 사용자 폴더와 각 하위 폴더를 반복하고 접두사 "album_"을 사용하여 하위 폴더 이름을 바꿔야 합니다. 내 최종 구조는 다음과 같아야 합니다.

사용자_1

---> 앨범_어린이1

---> 앨범_어린이2

사용자_29

---> 앨범_child37

---> 앨범_child56

다음을 사용하여 사용자 폴더의 이름을 바꿀 수 있습니다.

for f in * ; do mv "$f" user_"$f" ; done;

나는 다음과 같이 하위 디렉터리의 이름을 바꾸는 몇 가지 다른 방법을 시도해 왔습니다.

find . -maxdepth 2 -mindepth 2 -type d -exec mv '{}' album_'{}'

위 쿼리의 첫 번째 부분은 이름을 바꿔야 하는 모든 디렉터리를 반환합니다('find . -max 깊이 2 -min 깊이 2 -type d').

-exec 함수에서 디렉터리 이름에 액세스한 다음 접두사를 붙이려면 어떻게 해야 합니까?

답변1

노력하다:

find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'mv "$1" "./album_${1#./}"' mover {} \;

노트:

  1. ./대상 디렉터리의 이름을 구성하려면 디렉터리 이름에서 첫 번째 문자를 제거해야 합니다 . 이를 달성하기 위해 우리는 쉘의접두사 제거: ${1#./}.

  2. 명령이 실행되는 동안 디렉터리 이름이 바뀌는 경우 더 강력하기 때문에 -execdir대신 사용합니다 .-exec

  3. 표현식에서 bash -c '...' mover {}bash는 작은따옴표로 묶이고 파일 이름에 할당된 명령을 실행합니다 $0. 쉘이 오류 메시지를 작성해야 하는 경우가 아니면 사용되지 않습니다.mover$1{}$0

  4. 이 코드에는 bash 기능이 필요하지 않습니다. 모든 POSIX 쉘을 사용할 수 있습니다.

  5. 명령을 실행하기 전에 테스트하여 원하는 대로 작동하는지 확인하려면 echo다음과 같이 추가하십시오.

    find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'echo mv "$1" "./album_${1#./}"' mover {} \;
    

지침-exec mv '{}' album_'{}'

  1. 인용 하지 마세요 {}. find

  2. 제공된 파일 이름이 . find로 시작 하므로 ./양식이 album_{}성공하지 못합니다 .

다음 디렉토리를 고려해 보겠습니다.

$ ls *
user1:
child1  child2

user2:
child1  child2
Press any key to continue...

지금. 명령을 실행하고 새 디렉터리 이름을 확인해 보겠습니다.

$ find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'mv "$1" "./album_${1#./}"' mover {} \;
$ ls *
user1:
album_child1  album_child2

user2:
album_child1  album_child2

답변2

perl기본이 되셨다면rename

find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's|.*/\K|album_|' {} +
  • .*//디렉터리 경로의 마지막 항목 과 일치합니다 .
  • Lookbehind를 사용하면 \K이 경우 캡처 그룹이 필요하지 않을 수 있습니다.
  • 기본적으로 in은 .현재 디렉터리에 적용되므로 건너뛸 수 있습니다.find .find

-n올바른 이름 바꾸기가 표시된 후 이름 바꾸기에서 옵션을 제거하십시오.

예:

$ ls *
user_1:
child1  child2

user_29:
child37  child56

$ find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's|.*/\K|album_|' {} +
rename(./user_29/child37, ./user_29/album_child37)
rename(./user_29/child56, ./user_29/album_child56)
rename(./user_1/child2, ./user_1/album_child2)
rename(./user_1/child1, ./user_1/album_child1)
$ find -maxdepth 2 -mindepth 2 -type d -exec rename 's|.*/\K|album_|' {} +

$ ls *
user_1:
album_child1  album_child2

user_29:
album_child37  album_child56

답변3

저는 일반적으로 -exec를 직접 사용하지 않습니다. 문제가 발생하면 디버깅하기가 더 어렵기 때문입니다. find실행하기 전에 검토할 수 있는 스크립트를 작성 하세요 .

find . -maxdepth 2 -mindepth 2 -type d -printf 'mv "%P" "%h/album_%f"\n' > /tmp/rename.sh sh /tmp/rename.sh

답변4

Perl 기반 이름 바꾸기를 설치하면

rename 's!(.*/)!$1album_! if(-d $_)' user*/*

관련 정보