전체 디렉토리 트리를 소문자 이름으로 변경

전체 디렉토리 트리를 소문자 이름으로 변경

웹사이트 전환 작업 중입니다. 웹 서버에서 연결되고 제공되는 파일은 대소문자를 구분하지 않습니다. 그러나 Linux 시스템에 사이트를 덤프하고 데이터를 마이그레이션하는 스크립트를 작성 중입니다. 문제는 페이지의 링크 문자열과 파일 시스템의 실제 단어 대소문자 사이에 대소문자 구분 문제가 있다는 것입니다.

예를 들어, 페이지에는 <a href='/subfolder/PageName.asp'>실제 파일 에 대한 링크가 있을 수 있습니다. 이미지 /subfolder/pagename.asp에도 마찬가지입니다 .<img src='spacer_sm.gif'>Spacer_Sm.gif

그래서 내 생각은 모든 디렉토리와 파일 이름을 웹사이트에서 다운로드한 소문자로 변경하는 것입니다. 어떻게 해야 하나요?(더 좋은 방법이 있을까요?)

대소문자를 구분하지 않는 스위치가 있는 unix 명령이 있지만 PHP를 사용하고 있으므로 모든 파일 시스템 명령에 대소문자를 구분하는 옵션이 있는 것은 아닙니다.

답변1

지쉬

zmv -o-i '(**/)(*)' '$1${2:l}'

설명: zmv주어진 대체 텍스트를 기반으로 패턴과 일치하는 파일의 이름을 바꿉니다. -o-i각 기본 명령에 옵션을 전달합니다 -i(아래 참조). mv대체 텍스트에서 등 $1$2패턴의 연속된 괄호 그룹입니다. **모든 (하위)* 디렉터리를 재귀적으로 나타냅니다. 마지막 그룹 (/)은 대괄호로 묶인 그룹이 아니라 전역 한정자입니다. 즉, 디렉터리만 일치함을 의미합니다. 소문자로 ${2:l}변환합니다 .$2

펄 이름 바꾸기

여기서는 Debian 및 Ubuntu와 함께 제공되는 Perl 이름 바꾸기 스크립트를 사용하고 있습니다 /usr/bin/prename(일반적으로 사용 가능 rename). bash ≥4 또는 zsh를 사용하십시오.

shopt -s globstar  # only in bash
rename 's!/([^/]*/?)$!\L/$1!' **/*

다른 쉘의 경우:

find . -depth -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +

가지고 다닐 수 있는

재귀적으로:

find . -depth -exec sh -c '
    t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
    [ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

사용하면 -depth깊이 중첩된 디렉터리가 상위 디렉터리보다 먼저 처리됩니다.

답변2

귀하의 유닉스 버전에 이 기능이 있는지는 모르겠습니다 rename. 많은 Linux에 이 기능이 있고 저장소를 검색하면 Perl 패키지의 일부입니다.

find ./ -depth -exec rename -n 'y/[A-Z]/[a-z]/' {} ";"

위 버전이 함께 제공됩니다.

rename -n 

실제로 작업을 수행하지 않고 수행할 작업만 인쇄합니다. 실제로 이 작업을 수행하려면 -n을 생략합니다.

답변3

다음 디렉터리 구조에서는 작동하지 않습니다.

JKL/
deF/
ABC/DEf
ABC/gHi
ghi/jkL

다음은 실제 예입니다.

for i in `find | sort -r | sed '$d'`; do \
   b=${i%/*}; e=${i##*/}; mv $i $b'/'${e,,}; done

bvars에 대한 설명 e:

man bash

그런 다음 다음 키 시퀀스를 사용하십시오./,,Enterbb

답변4

허용된 답변은 모든 디렉토리를 한 번에 변경하려고 시도했기 때문에 나에게 적합하지 않았습니다. 위의 Gilles의 휴대용 솔루션과 매우 유사한 stackexchange의 또 다른 솔루션을 찾았습니다. Baramin에서 -
https://stackoverflow.com/questions/4268591/unix-rename-files-directories-to-uppercase

여기에 복사했습니다.

find . -depth | \
while read LONG; do
   SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' )
   DIR=$( dirname "$LONG" )
   if [ "${LONG}" != "${DIR}/${SHORT}"  ]; then
     mv "${LONG}" "${DIR}/${SHORT}"
   fi
done

tr 명령을 다음과 같이 변경했습니다: sed s/cat/dog/g

위 링크의 Baramin에게 감사드립니다.

관련 정보