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

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

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

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

대소 문자를 구분하지 않는 스위치가있는 유닉스 명령이 있더라도 PHP를 사용하고 있으므로 모든 파일 시스템 명령에 대소 문자 구분 옵션이 없습니다.



답변

유닉스 맛에가 있는지 모르겠습니다 rename. 많은 Linux가 있으며 저장소를 검색하면 perl 패키지의 일부입니다.

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

위의 버전

rename -n 

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


답변

Zsh

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

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

펄 이름 바꾸기

여기에서는 데비안과 우분투가 제공하는 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하면 깊이 중첩 된 디렉토리가 상위 항목보다 먼저 처리됩니다.


답변

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

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

bevars 에 대한 설명 :

man bash

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


답변

허용 된 답변은 모든 디렉토리를 한 번에 변경하려고 시도했기 때문에 작동하지 않았습니다. 위의 Gilles의 휴대용 솔루션과 매우 비슷한 stackexchange에 대한 또 다른 솔루션을 찾았습니다 : Baramin- https : //.com

여기에 복사했습니다.

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에게 감사드립니다.


답변


답글 남기기