디렉토리 아래의 모든 디렉토리를 소문자로 변경

디렉토리 아래의 모든 디렉토리를 소문자로 변경

디렉토리 아래의 모든 디렉토리 이름을 소문자로 만들고 싶습니다. 이 작업을 수행하려면 어떤 명령을 사용할 수 있나요?

답변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 -cfind

$ (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

관련 정보