문제

내가 이름을 바꾸려면 완벽한 폴더 트리 재귀적으로는 아무도 대문자 나타나는(그것의 C++소스 코드,그러나는 문제가 되지 않).보너스 포인트 무시코 SVN 제어 파일/폴더에 있습니다.선호하는 방법을 것 쉘 스크립트,이후 쉘에서 사용할 수 있어야 모든 리눅스.

몇 가지 유효한 인수에 대한 상세정보 파일의 이름 바꾸기.

  1. 내가 생각하는 파일과 같은 소문자로 이름을 덮어,그것은 사용자의 문제입니다.선택하는 경우에는 경우를 무시하는 파일 시스템을 덮어쓸 것 첫 번째 중 하나로 후반,too.

  2. 해 A-Z 변환 및 그들을 a-z,다른 모든 것은 그냥 부르는 문제에 대한(이상 소스 코드).

  3. 스크립트는 것을 실행하는 데 필요한 빌드를 리눅스 시스템에서,그래서 저는 생각을 변경하여 CVS 또는 SVN 제어 파일을 생략해야 합니다.후에도,그것은 단지 처음습니다.어쩌면"내보내기"는 것이 더 적절하다.

도움이 되었습니까?

해결책

간결한 버전을 사용합니다 "rename" 명령.

find my_root_dir -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

이렇게하면 파일 이전에 이름이 바뀌고 파일을 존재하지 않는 디렉토리로 옮기려고하는 디렉토리의 문제가 피합니다 (예 : "A/A" ~ 안으로 "a/a").

또는 사용하지 않고 더 장악 한 버전 "rename".

for SRC in `find my_root_dir -depth`
do
    DST=`dirname "${SRC}"`/`basename "${SRC}" | tr '[A-Z]' '[a-z]'`
    if [ "${SRC}" != "${DST}" ]
    then
        [ ! -e "${DST}" ] && mv -T "${SRC}" "${DST}" || echo "${SRC} was not renamed"
    fi
done

추신

후자는 Move Command를 사용하여 더 많은 유연성을 허용합니다 (예 : "svn mv").

다른 팁

여전히 나는 여전히 좋아합니다

rename 'y/A-Z/a-z/' *

OS X의 HFS+와 같은 CASE Insensitive 파일 시스템에서는 -f 플래그를 추가 할 것입니다.

rename -f 'y/A-Z/a-z/' *
for f in `find`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done

효율성을 신경 쓰지 않아도됩니다.

zip -r foo.zip foo/*
unzip -LL foo.zip

위의 대부분의 답변은 이상한 문자가 포함 된 이름을 다루지 않기 때문에 위험합니다. 이런 종류의 가장 안전한 베팅은 find의 -print0 옵션을 사용하는 것입니다.이 옵션은 n 대신 ascii nul로 파일 이름을 종료합니다. 여기 에이 스크립트를 제출합니다.이 스크립트는 파일 만 변경하지 않고 찾기를 혼동하지 않도록 파일 만 변경합니다.

find .  -type f -print0 | xargs -0n 1 bash -c \
's=$(dirname "$0")/$(basename "$0"); 
d=$(dirname "$0")/$(basename "$0"|tr "[A-Z]" "[a-z]"); mv -f "$s" "$d"'

나는 그것을 테스트했고 그것은 공백, 모든 종류의 따옴표 등을 포함하는 파일 이름으로 작동합니다.

touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash

... 글쎄요 ...

이미 가지고 있거나 설정 한 경우 작동합니다 이름 바꾸기 명령 (예 : Mac에서 BREW 설치를 통해) :

rename --lower-case --force somedir/*

너희들은 너무 복잡한 일을 좋아하는 사람 ..

이름 바꾸기 'y/az/az/' *

이것은 Centos/Redhat 또는 기타 분포에서 작동하지 않습니다. rename Perl 스크립트 :

for i in $( ls | grep [A-Z] ); do mv -i "$i" "`echo $i | tr 'A-Z' 'a-z'`"; done

원천: https://linuxconfig.org/rename-all-files-from-uppercase-to-lowercase-characters

(일부 배포에서는 기본값이 있습니다 rename 명령은 util-linux에서 제공되며, 그것은 다르고 양립 할 수없는 도구입니다)

Larry Wall의 Filename Fixer 사용

$op = shift or die $help;
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

간단합니다

find | fix 'tr/A-Z/a-z/'

(수정이 위의 스크립트 인 경우)

원래 질문은 SVN 및 CVS 디렉토리를 무시하는 것을 요청했는데,이 디렉토리는 찾기 명령에 -Prune을 추가하여 수행 할 수 있습니다. 예를 들어 CVS를 무시하려면 :

find . -name CVS -prune -o -exec mv '{}' `echo {} | tr '[A-Z]' '[a-z]'` \; -print

편집] 나는 이것을 시도했고, 발견 안에있는 소문자 번역을 포함시키는 것은 실제로 이해하지 못하는 이유 때문에 효과가 없었습니다. 따라서 다음을 수정하십시오.

$> cat > tolower
#!/bin/bash
mv $1 `echo $1 | tr '[:upper:]' '[:lower:]'`
^D
$> chmod u+x tolower 
$> find . -name CVS -prune -o -exec tolower '{}'  \;

이안

Bash Shell 스크립트를 사용하는 내 차선책은 다음과 같습니다.

#!/bin/bash
# first, rename all folders
for f in `find . -depth ! -name CVS -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming folder $f"
      mv -f "$f" "$g"
   fi
done

# now, rename all files
for f in `find . ! -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming file $f"
      mv -f "$f" "$g"
   fi
done

편집 : 지금까지 제안을 바탕으로 몇 가지 수정을했습니다. 이제 폴더가 모두 올바르게 바뀌고 MV는 권한이 일치하지 않을 때 질문을하지 않으며 CVS 폴더가 이름이 바뀌지 않았습니다 (불행히도 해당 폴더 내부의 CVS 제어 파일이 이름이 바뀌 었습니다).

편집 : "find -depth"및 "find | sort -r"이후 모두 폴더 목록을 사용 가능한 이름 변경 순서로 반환하기 때문에 폴더 검색에 "-depth"를 사용하는 것을 선호합니다.

요청한 작업을 수행하는 작은 쉘 스크립트입니다.

root_directory="${1?-please specify parent directory}"
do_it () {
    awk '{ lc= tolower($0); if (lc != $0) print "mv \""  $0 "\" \"" lc "\"" }' | sh
}
# first the folders
find "$root_directory" -depth -type d | do_it
find "$root_directory" ! -type d | do_it

첫 번째 찾기에서 약한 동작에 유의하십시오.

이전에 게시 된 것은 상자에서 완벽하게 작동하거나 간단한 경우에 대한 몇 가지 조정이 있지만 배치 이름을 실행하기 전에 고려해야 할 상황이 있습니다.

  1. 경로 계층 구조에서 동일한 레벨에 두 개 이상의 이름이있는 경우 어떻게 해야하는지, 예 : ABCdef, abcDEF 그리고 aBcDeF? 이름 변경 스크립트가 중단되거나 경고하고 계속해야합니까?

  2. US-ASCII 이름이 아닌 소문자를 어떻게 정의합니까? 그러한 이름이있을 수 있다면, 한 번의 수표와 제외 패스를 먼저 수행해야합니까?

  3. CVS 또는 SVN 작업 사본에서 이름 바꾸기 작업을 실행중인 경우 파일 또는 디렉토리 이름에서 케이스를 변경하면 작업 사본이 손상 될 수 있습니다. 스크립트가 .SVN/항목 또는 CVS/항목과 같은 내부 관리 파일을 찾아서 조정해야합니까?

for f in `find -depth`; do mv ${f} ${f,,} ; done

find -depth 디렉토리의 내용을 디렉토리 자체 앞에 인쇄하여 각 파일과 디렉토리를 인쇄합니다. ${f,,} 파일 이름을 낮추십시오.

MacOS와 함께

설치 rename 패키지,

brew install rename

사용,

find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"                       

이 명령은 모든 파일을 a로 찾습니다 *.py 확장 및 파일 이름을 소문자로 변환합니다.

`f` - forces a rename

예를 들어,

$ find . -iname "*.py" -type f
./sample/Sample_File.py
./sample_file.py
$ find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"
$ find . -iname "*.py" -type f
./sample/sample_file.py
./sample_file.py

휴대용은 아니지만 ZSH 만이지만 간결합니다.

먼저 확인하십시오 zmv 로드되었습니다.

autoload -U zmv

또한 확인하십시오 extendedglob 켜져 있습니다 :

setopt extendedglob

그런 다음 사용하십시오 :

zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'

이름이없는 파일과 디렉토리를 재귀 적으로 CVS.

OSX에서 MV -F는 "동일한 파일"오류를 보여 주므로 두 번 이름을 바꿉니다.

for i in `find . -name "*" -type f |grep -e "[A-Z]"`; do j=`echo $i | tr '[A-Z]' '[a-z]' | sed s/\-1$//`; mv $i $i-1; mv $i-1 $j; done

Windows 7의 Cygwin 설정 에서이 작업을 수행해야했는데 위의 제안과 함께 구문 오류가 발생한 것으로 나타 났지만 (작업 옵션을 놓쳤을 지 모르지만) 우 부투 포럼 캔에서 일했습니다 :-)

ls | while read upName; do loName=`echo "${upName}" | tr '[:upper:]' '[:lower:]'`; mv "$upName" "$loName"; done

(NB는 이전에 공백을 사용하여 밑줄로 교체했습니다.

for f in *\ *; do mv "$f" "${f// /_}"; done

공백이나 슬래시가없는 경로를 낙관적으로 가정하지 않기 위해이 상황에서 파이썬에 도달 할 것입니다. 나는 또한 그것을 발견했다 python2 더 많은 장소에 설치되는 경향이 있습니다 rename.

#!/usr/bin/env python2
import sys, os

def rename_dir(directory):
  print('DEBUG: rename('+directory+')')
  # rename current directory if needed
  os.rename(directory, directory.lower())
  directory = directory.lower()

  # rename children
  for fn in os.listdir(directory):
    path = os.path.join(directory, fn)
    os.rename(path, path.lower())
    path = path.lower()

    # rename children within, if this child is a directory
    if os.path.isdir(path):
        rename_dir(path)

# run program, using the first argument passed to this python script as the name of the folder
rename_dir(sys.argv[1])

길지만 "놀라움과 설치 없음"

이 스크립트 공백, 따옴표, 기타로 파일 이름을 처리합니다 특이한 문자 및 유니 코드, 케이스 insensitive filesystems 및 대부분의 Unix-Y 환경에서 작동합니다. Bash and Awk가 설치되어 있습니다 (즉, 거의 모두). 또한 (파일 이름을 대문자로 남겨 두는 경우) 충돌을보고하고 물론 파일 및 디렉토리를 모두 이름을 바꾸고 재귀 적으로 작동합니다. 마지막으로 적응력이 뛰어납니다. 찾은 명령을 조정하여 원하는 파일/듀스를 타겟팅하여 다른 이름 조작을 조정할 수 있습니다. "유니 코드를 처리"한다는 점에 주목하십시오. 나는 그것이 실제로 사건을 변환 할 것임을 의미합니다 (사용하는 답변처럼 무시하지 마십시오. tr).

# adapt the following command _IF_ you want to deal with specific files/dirs
find . -depth -mindepth 1 -exec bash -c '
  for file do
    # adapt the awk command if you wish to rename to something other than lowercase
    newname=$(dirname "$file")/$(basename "$file" | awk "{print tolower(\$0)}")
    if [ "$file" != "$newname" ] ; then
        # the extra step with the temp filename is for case-insensitive filesystems
        if [ ! -e "$newname" ] && [ ! -e "$newname.lcrnm.tmp" ] ; then
           mv -T "$file" "$newname.lcrnm.tmp" && mv -T "$newname.lcrnm.tmp" "$newname" 
        else
           echo "ERROR: Name already exists: $newname"
        fi
    fi    
  done
' sh {} +

참조

내 스크립트는 다음과 같은 훌륭한 답변을 기반으로합니다.

https://unix.stackexchange.com/questions/9496/looping-through-files-with-in-the-names

Bash에서 문자열을 소문자로 변환하는 방법은 무엇입니까?

MacOSX에서 찾은 가장 간단한 접근 방식은 이름 바꾸기 패키지를 사용하는 것이 었습니다. http://plasmasturm.org/code/rename/:

brew install rename
rename --force --lower-case --nows *

-대상 이름이있는 파일이 이미 존재하는 경우에도 이름 바꾸기.

-lower-case는 파일 이름을 모든 소문자로 변환합니다.

-NOW는 파일 이름의 모든 공백 시퀀스를 단일 밑줄 문자로 바꿉니다.

( find YOURDIR -type d | sort -r;
  find yourdir -type f ) |
grep -v /CVS | grep -v /SVN |
while read f; do mv -v $f `echo $f | tr '[A-Z]' '[a-z]'`; done

먼저 디렉토리의 이름을 바꾸십시오 정렬 -r (-Depth를 사용할 수없는 경우). 그런 다음 파일입니다. 그 다음에 grep -v /cvs 대신에 찾기 ...- 자두 더 간단하기 때문입니다. 큰 디렉토리의 경우 F를 위해 ... 일부 쉘 버퍼를 넘칠 수 있습니다. 사용 찾기 ... | 읽는 동안 그것을 피하기 위해.

그리고 네, 이것은 경우에만 다른 파일을 깎을 것입니다 ...

Slugify Rename (Regex)

OP가 요청한 내용이 아니라이 페이지에서 찾기를 바랐던 것 :

파일 이름 변경을위한 "Slugify"버전으로 URL과 유사합니다.
(즉, 영숫자, 점 및 대시 만 포함) :

rename "s/[^a-zA-Z0-9\.]+/-/g" filename

사용하는 경우 아치 리눅스, 당신은 설치할 수 있습니다 rename 패키지 AUR 그것은 제공합니다 renamexm 명령으로 /usr/bin/renamexm 실행 파일과 그 수동 함께 페이지.

파일과 디렉토리의 이름을 빠르게 바꾸는 것은 정말 강력한 도구입니다.

소문자로 변환하십시오

rename -l Developers.mp3 # or --lowcase

대문자로 변환하십시오

rename -u developers.mp3 # or --upcase, long option

다른 옵션

-R --recursive # directory and its children

-t --test # dry run, output but don't rename

-o --owner # change file owner as well to user specified

-v --verbose # output what file is renamed and its new name

-s/str/str2 # substite string on pattern

--yes # Confirm all actions

조판을 제안하는 사람이 없습니까?

typeset -l new        # always lowercase
find $topPoint |      # not using xargs to make this more readable
  while read old
  do mv "$old" "$new" # quotes for those annoying embedded spaces
  done

Windows에서 git bash와 같은 에뮬레이션에서는 Windows가 후드에서는 대체 민감하지 않기 때문에 이것은 실패 할 수 있습니다. 이를 위해 MV가 "$ old.tmp"와 같이 먼저 다른 이름으로 파일을 추가 한 다음 $ new에 추가하십시오.

이것은 MacOS에서도 잘 작동합니다.

ruby -e "Dir['*'].each { |p| File.rename(p, p.downcase) }"
find . -depth -name '*[A-Z]*'|sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'|sh

내가 시도하지 않은 더 정교한 스크립트는 여기에 언급하지만,없음 단일 명령행 versions on 능 NAS. rename 사용할 수 없는 많은 변형 find 기 때문에 실패할 것 같다 붙는 이름의 이미 이름을 변경한 경로(예를 들어,만약 발견 ./FOO 다음 ./FOO/BAR, 이름 바꾸기 ./FOO 하기 ./foo 여전히 계속 목록 ./FOO/BAR 에도 불구하는 경로가 더 이상 유효하지 않음).위 명령은 나를 위해 일하지 않고 어떤 문제입니다.

다음은 설명의 각 부분의 명령:


find . -depth -name '*[A-Z]*'

이 모든 파일을 찾을 수 있 현재 디렉터리에서(변경 . 무엇을 원하는 디렉터리 프로세스)사용하여 깊이 첫 번째 검색(eg., 그것은 목록 ./foo/bar./foo),하지만 파일을 포함하는 대문자.이 -name 필터만 적용됩니다 기본 파일의 이름,전체 경로입니다.그래서 이 목록 ./FOO/BAR./FOO/bar.이것은 확인,우리가 원하지 않는 이름 바꾸기 ./FOO/bar.우리는 원하는 이름을 바꾸어 ./FOO 하지만,하지만 하나 나와 나중에(는 이유입 -depth 은 중요합니다).

이 명령에 자체에 특히 유용하여 파일을 찾은 이름을 바꾸려는 첫 번째 장소입니다.이용 후 전체 이름을 변경 명령어를 검색하는 파일에 대한 아직도 대체되었기 때문에 파일 이름의 충돌 또는 오류가 있습니다.


sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'

이 부분을 읽어 파일로 출력하여 find 와 형식에서 그들을 mv 명령을 사용하여 정기적인 표현입니다.이 -n 옵션 중 sed 에서 인쇄하는 입력,그리고 p 명령어에서 검색-과-대체 regex 출력된 텍스트입니다.

Regex 자체로 구성되어 있는 두 개의 캡처:부분까지/(는 디렉토리에 파일),그리고 파일명 자체입니다.디렉토리이 그대로 남아있지만,파일 이름이 변하는 소문자입니다.경우에 따라서, find 출력 ./FOO/BAR, 이 될 것입 mv -n -v -T ./FOO/BAR ./FOO/bar.이 -n 옵션 mv 확인 기존의 소문자로 파일은 덮어쓰지 않습니다.이 -v 옵션 mv 출력 모든 변화는(거나 만들지 않는 경우- ./FOO/bar 이미 존재하는 출력 같은 것 ./FOO/BAR -> ./FOO/BAR, 할 수 없이 변경되었을).이 -T 여기에 매우 중요-그것을 취급 대상으로 파일 디렉토리에 있습니다.이 있는지 확인 ./FOO/BAR 지 않으로 이동 ./FOO/bar 는 경우에는 디렉토리 일어나는 존재합니다.

이와 함께 find 목록을 생성하는 명령이 실행됩니다(편리한 것을 확인하기 위해 수행됩니다 실제로 그 일)


sh

이악하기가 쉽습니다.그것은 경로의 모든 생성 mv 명령하는 셸리가 들어 있습니다.로 바꿀 수 있습니다 bash 나 쉘의습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top