나는 스크립트를 통해 파일과 폴더를 정리하려고 노력합니다. 내 파일의 첫 글자로 폴더를 생성하고 그곳으로 이동합니다.
처음에는 스크립트가 작업을 수행하지만 새 파일을 만들고 스크립트를 다시 실행하면 폴더 내에 새 하위 폴더가 생성되는 식입니다.
예를 들어 T/T/toto.txt
.
내 스크립트:
for first in $(ls -1 | sed 's/^\(.\).*$/\1/' | tr '[a-z0-9]' '[A-Z0-9]' | uniq)
do
mkdir tmp
mv "$first"* tmp/
lower=$(echo $first | tr '[A-Z]' '[a-z]')
mv "$lower"* tmp/
mv tmp/ "$first";
done
답변1
스크립트가 실행 중입니다.목차및 디렉토리가 아닌 파일을 정렬하고 싶은 단일 문자 디렉토리인 경우에도 이름을 기준으로 하위 디렉토리로 이동합니다. 이것이 새 디렉토리가 나타나는 방식입니다. 또한 귀하의 코드는 셸이 더 빠르고 안전하게 수행할 수 있는 작업을 수행하기 위해 불필요하게 sed
etc.를 사용합니다. 또한 파일 이름을 반복하는 스크립트에서는 절대 사용해서는 안 됩니다(예:tr
bash
ls
왜 `ls`를 구문 분석하지 *않나요*(그리고 어떻게 수행합니까)?왜).
또 다른 문제는 이름이 동일한 문자로 시작하는 수천 개의 파일이 있는 경우 이 mv "$first"* tmp/
명령(또는 두 번째 명령 mv
)이 "인수 목록이 너무 김" 오류와 함께 실패할 수 있다는 것입니다(예:ls에 대한 매개변수 목록이 너무 깁니다.;이 질문은 ) mv
뿐만 아니라 다른 모든 외부 명령 에도 적용됩니다 ls
.
이러한 문제를 해결하는 예제 스크립트는 bash
Except from 및 mkdir
의 함수 만 사용합니다 mv
.
#!/bin/bash
shopt -s nullglob # makes the loop not loop at all if there are no files
for name in *; do
if [[ -d $name ]] && [[ $name == ? ]]; then
# skip directories that have single character names
continue
fi
# get first character in filename
first=${name:0:1}
# compute destination directory name from this first
# character by uppercasing it
destdir=${first^}
# make that directory if it does not already exist
mkdir -p -- "$destdir"
# move the file into place (name collisions not checked for)
mv -- "$name" "$destdir"
done
--
옵션을 사용하고 대시로 시작될 수 있는 파일 이름을 mkdir
방지합니다 (예:mv
"--"(이중 대시)은(는) 무슨 뜻인가요?).
이 스크립트의 주요 차이점은 여러분처럼 첫 번째 문자를 반복하는 대신 디렉터리의 이름을 반복한다는 것입니다.