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


12

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

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

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

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


2
비슷한 이전 질문을 참조하십시오 . 질문이 좀 더 구체적이기 때문에 더 간단한 대답을 다시 게시했습니다.
Gilles 'SO- 악한 중지'

답변:


8

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

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

위의 버전

rename -n 

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


'y/[A-Z]/[a-z]/'일부 '언어'또는 정규식은 무엇입니까 ?
user394

음, 이후는 rename(A)의 일부 perl나 펄 생각, 패키지,하지만 패턴에 사용되는 sed아마에서 너무 AWK아니라. 나는 sed조용히 잘 알고 있습니다. 나는 번역 ytranslate하거나 map,하지만 난 곳은 문자의 기원에서 알 수 없습니다.
사용자가 알 수 없음

그의 대답에서 Gilles rename는 perl 스크립트 라고 말합니다 .
user394

예, 그리고 당신은 펄 정규식을 사용하여 파일 이름을 수정할 수 있습니다.
사용자가 알 수 없음

9

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하면 깊이 중첩 된 디렉토리가 상위 항목보다 먼저 처리됩니다.


1

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

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


0

허용 된 답변은 모든 디렉토리를 한 번에 변경하려고 시도했기 때문에 작동하지 않았습니다. 위의 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에게 감사드립니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.