하위 디렉터리의 이름을 바꾸지 않고 디렉터리의 모든 파일 이름을 소문자로 바꾸고 싶습니다. 이름 바꾸기 기능에 대해 알고 있지만 파일과 하위 디렉터리의 이름을 바꾸는 것은 바람직하지 않습니다. 도와주세요?
답변1
Perl 표현식으로 모든 작업을 수행할 수 있습니다.
-f
일반 파일(디렉토리 아님)만 이름이 바뀌도록 일반 파일 테스트를 사용합니다 .
이것은 작동합니다:
rename 'y/A-Z/a-z/ if -f;' ./*
( ./*
not을 사용하면 *
파일 이름이 대시(-)로 시작하더라도 파일 이름이 옵션으로 해석되지 않습니다.
답변2
그리고 zsh
:
autoload zmv # best in ~/.zshrc
zmv '*(#q^/)' '${(L)f}'
디렉토리를 제외한 모든 유형의 파일 이름을 바꿉니다. 또는:
zmv '*(#q.)' '${(L)f}'
일반 파일만 이름이 변경됩니다. 숨겨진 파일도 포함하려면 D
glob 한정자를 추가하세요.
예( -n
시험 실행용):
$ ls -alQF
total 132
drwxr-xr-x 3 stephane stephane 4096 Oct 27 09:11 "."/
drwxr-xr-x 533 stephane stephane 122880 Oct 27 09:11 ".."/
drwxr-xr-x 2 stephane stephane 4096 Oct 27 09:07 "DIR"/
lrwxrwxrwx 1 stephane stephane 3 Oct 27 09:07 "DIR-LINK" -> "DIR"/
prw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "FIFO"|
-rw-r--r-- 1 stephane stephane 0 Oct 27 09:11 ".HIDDEN FILE"
-rw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "HOLIDAYS IN МОСВА\nRED SQUARE.JPG"
lrwxrwxrwx 1 stephane stephane 23 Oct 27 09:08 "MY-RÉSUMÉ.PDF" -> "STÉPHANE'S RÉSUMÉ.PDF"
-rw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "--READ-ME--.TXT"
srwxr-xr-x 1 stephane stephane 0 Oct 27 09:09 "SOCKET"=
-rw-r--r-- 1 stephane stephane 0 Oct 27 09:07 "STÉPHANE'S RÉSUMÉ.PDF"
$ zmv -n '*(#q^/)' '${(L)f}'
mv -- DIR-LINK dir-link
mv -- FIFO fifo
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- MY-RÉSUMÉ.PDF my-résumé.pdf
mv -- --READ-ME--.TXT --read-me--.txt
mv -- SOCKET socket
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf
$ zmv -n '*(#q.)' '${(L)f}'
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- --READ-ME--.TXT --read-me--.txt
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf
$ zmv -n '*(#qD.)' '${(L)f}'
mv -- .HIDDEN\ FILE .hidden\ file
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- --READ-ME--.TXT --read-me--.txt
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf
이들 중 일부가 일부 심볼릭 링크를 어떻게 깨뜨리는지 확인하세요.
답변3
var를 소문자로 포맷하면 소문자로 변환할 수 있습니다.
편집: 솔루션 find
을 for
.
처음 시도한 해결책 find
은 -type f
. 이로 인해-maxdepth 1
typeset -l smallfile
echo "Find solution looks OK but read more..."
find .-maxdepth 1 -type f| while read file; do
smallfile="${file}"
mv "${file}" "${smallfile}"
done
내 생각에 이 구조는 공백이 있는 파일 이름을 올바르게 처리한다고 생각합니다. "공백이 있는 파일"과 같은 파일 이름으로 테스트했습니다. @Chazelas는 파일 이름이 공백("너무 나쁨")으로 끝나기 때문에 이 솔루션이 실패한다고 올바르게 언급했습니다. 또 다른 의견에서는 수정 방법에 대해 설명합니다. find
- command: ( 지원해야 하는 find ... -print0 | while IFS= read -rd '' file
것 , 주로 및 ). 이미 루프를 사용하고 있으므로 를 사용 하여 현재 항목( 에서 제공 )이 일반 파일인지 확인할 수도 있습니다. 간단한 for 루프가 있는 솔루션을 찾았고 테스트 코드를 포함하여 여기에 표시합니다.find
print0
bash
zsh
test
*
#!/bin/bash
clear
rm -rf testfiles 2>/dev/null
mkdir -p testfiles/SomeDir #2>/dev/null
mkdir testfiles/"Crazy Dir" 2>/dev/null
touch testfiles/Aha testfiles/"File with Spaces" testfiles/"End with space "
ls -lQ testfiles
echo ===================
typeset -l smallfile
for file in testfiles/* # Stack's formatting thinks /* starts comment, so I close that here: */
do
if [ -f "${file}" ]; then
smallfile="${file}"
# echo mv "${file}" "${smallfile}"
mv "${file}" "${smallfile}"
fi
done
echo ===================
ls -lQ testfiles
현재 디렉터리의 경우 testdir/
for 루프에서 제거하세요.
답변4
이 oneliner는 이 문제를 해결합니다.
find path-to-search -depth -type f -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
아!