파일을 알파벳순 폴더로 정렬하는 Bash 스크립트

파일을 알파벳순 폴더로 정렬하는 Bash 스크립트

나는 스크립트를 통해 파일과 폴더를 정리하려고 노력합니다. 내 파일의 첫 글자로 폴더를 생성하고 그곳으로 이동합니다.

처음에는 스크립트가 작업을 수행하지만 새 파일을 만들고 스크립트를 다시 실행하면 폴더 내에 새 하위 폴더가 생성되는 식입니다.

예를 들어 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

스크립트가 실행 중입니다.목차및 디렉토리가 아닌 파일을 정렬하고 싶은 단일 문자 디렉토리인 경우에도 이름을 기준으로 하위 디렉토리로 이동합니다. 이것이 새 디렉토리가 나타나는 방식입니다. 또한 귀하의 코드는 셸이 더 빠르고 안전하게 수행할 수 있는 작업을 수행하기 위해 불필요하게 sedetc.를 사용합니다. 또한 파일 이름을 반복하는 스크립트에서는 절대 사용해서는 안 됩니다(예:trbashls왜 `ls`를 구문 분석하지 *않나요*(그리고 어떻게 수행합니까)?왜).

또 다른 문제는 이름이 동일한 문자로 시작하는 수천 개의 파일이 있는 경우 이 mv "$first"* tmp/명령(또는 두 번째 명령 mv)이 "인수 목록이 너무 김" 오류와 함께 실패할 수 있다는 것입니다(예:ls에 대한 매개변수 목록이 너무 깁니다.;이 질문은 ) mv뿐만 아니라 다른 모든 외부 명령 에도 적용됩니다 ls.

이러한 문제를 해결하는 예제 스크립트는 bashExcept 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"--"(이중 대시)은(는) 무슨 뜻인가요?).

이 스크립트의 주요 차이점은 여러분처럼 첫 번째 문자를 반복하는 대신 디렉터리의 이름을 반복한다는 것입니다.

관련 정보