현재 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#./}
.명령이 실행되는 동안 디렉터리 이름이 바뀌는 경우 더 강력하기 때문에
-execdir
대신 사용합니다 .-exec
표현식에서
bash -c '...' mover {}
bash는 작은따옴표로 묶이고 파일 이름에 할당된 명령을 실행합니다$0
. 쉘이 오류 메시지를 작성해야 하는 경우가 아니면 사용되지 않습니다.mover
$1
{}
$0
이 코드에는 bash 기능이 필요하지 않습니다. 모든 POSIX 쉘을 사용할 수 있습니다.
명령을 실행하기 전에 테스트하여 원하는 대로 작동하는지 확인하려면
echo
다음과 같이 추가하십시오.find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'echo mv "$1" "./album_${1#./}"' mover {} \;
지침-exec mv '{}' album_'{}'
인용 하지 마세요
{}
.find
제공된 파일 이름이 .
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*/*