디렉토리 아래의 모든 디렉토리 이름을 소문자로 만들고 싶습니다. 이 작업을 수행하려면 어떤 명령을 사용할 수 있나요?
답변1
모든 디렉토리가 한 수준에 있습니까, 아니면 재귀적으로 있습니까?
지쉬
한 수준에서:
autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'
재귀적으로:
zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'
설명: zmv
주어진 대체 텍스트를 기반으로 패턴과 일치하는 파일의 이름을 바꿉니다. -o-i
각 기본 명령에 옵션을 전달합니다 -i
(아래 참조). mv
대체 텍스트에서 등 $1
은 $2
패턴의 연속된 괄호 그룹입니다. **
모든 (하위)* 디렉터리를 재귀적으로 나타냅니다. 마지막 그룹 (/)
은 대괄호로 묶인 그룹이 아니라 전역 한정자입니다. 즉, 디렉터리만 일치함을 의미합니다. 소문자로 ${2:l}
변환합니다 .$2
가지고 다닐 수 있는
한 수준에서:
for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done
마지막은 /
일치하는 디렉터리를 제한하고 mv -i
충돌이 발생할 경우 확인이 필요합니다. -i
충돌 시 덮어쓰려면 삭제한 다음 를 사용하세요 yes n | for …
. 메시지가 표시되지 않으며 잠재적으로 충돌할 수 있는 이름 바꾸기를 수행하지 마십시오.
재귀적으로:
find root/* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;
사용하면 -depth
깊이 중첩된 디렉터리가 상위 디렉터리보다 먼저 처리됩니다. 이름 처리는 존재에 의존합니다 /
. 현재 디렉토리에서 작업을 호출하려면 사용하십시오 ./*
(대처할 수 있도록 쉘 스크립트를 조정 .
하거나 *
독자에게 연습으로 남겨두십시오).
펄 이름 바꾸기
여기서는 Debian 및 Ubuntu와 함께 제공되는 Perl 이름 바꾸기 스크립트를 사용하고 있습니다 /usr/bin/prename
(일반적으로 사용 가능 rename
). 한 수준에서:
rename 's!/([^/]*/?)$!\L/$1!' root/*/
bash ≥4 또는 zsh를 사용하여 재귀적으로:
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!\L/$1!' root/**/*/
재귀적이고 이식 가능하게:
find root -depth -type d -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +
답변2
이 작업을 수행할 수 있는 단일 명령은 없지만 다음과 같이 할 수 있습니다.
for fd in */; do
#get lower case version
fd_lower=$(printf %s "$fd" | tr A-Z a-z)
#if it wasn't already lowercase, move it.
[ "$fd" != "$fd_lower" ] && mv "$fd" "$fd_lower"
done
충분히 강력해야 하는 경우 대소문자만 다른 두 개의 디렉터리가 이미 있는 경우를 고려해야 합니다.
한 줄로:
for fd in */; do fd_lower=$(printf %s "$fd" | tr A-Z a-z) && [ "$fd" != "$fd_lower" ] && mv "$fd" "$fd_lower"; done
답변3
저는 이것이 단순한 도전이라고 생각합니다 :) 먼저 테스트 케이스를 구축합니다.
$ for d in foo Bar eVe; do mkdir -p dcthis/$d; touch dcthis/a${d}.txt; done
$ ls dcthis/
Bar aBar.txt aeVe.txt afoo.txt eVe foo
find
예전에는 디렉토리를 대문자로 하고 .sh -c 'mv {}
echo {} | tr [:upper:] [:lower:]
'sh -c
find
$ (cd dcthis && find . -maxdepth 1 -type d -path '*[A-Z]*' -exec sh -c 'mv {} `echo {} | tr [:upper:] [:lower:]`' \;)
$ ls dcthis/
aBar.txt aeVe.txt afoo.txt bar eve foo
참고: 이 솔루션은 충돌을 일으킬 수 있는 사례를 확인하지 않습니다!
답변4
find -execdir rename
기본 이름에만 영향을 미치는 정규식을 사용하여 파일과 디렉터리의 이름을 바꿉니다.
따라서 접두사에 대해 다음을 수행할 수 있습니다.
PATH=/usr/bin find . -depth -execdir rename 's/(.*)/\L$1/' '{}' \;
또는 파일에만 영향을 줍니다.
PATH=/usr/bin find . -type f -execdir rename 's/(.*)/\L$1/' '{}' \;
-execdir
기본 이름만 입력하기 전에 먼저 해당 디렉토리로 이동하세요 cd
.
아래에서 이에 대해 더 자세히 설명합니다.https://stackoverflow.com/questions/16541582/find-multiple-files-and-rename-them-in-linux/54163971#54163971