특정 파일 형식을 찾고 이동할 수 있도록 bash 스크립트를 개선하는 데 도움을 주세요.

특정 파일 형식을 찾고 이동할 수 있도록 bash 스크립트를 개선하는 데 도움을 주세요.

나는 1) 특정 디렉토리($DIR1)에 있는 모든 이미지 파일을 찾아 다른 디렉토리($DIR2)로 이동한 다음 2) 동일한 $DIR1에 있는 모든 비디오 파일을 찾아서 이동하는 bash 스크립트를 작성했습니다. 마지막으로 $DIR1에 남아 있는 모든 파일을 찾아 네 번째 디렉터리($DIR4)로 이동합니다. 최종 결과는 스크립트 끝에서 $DIR1이 비어 있다는 것입니다.

#!/bin/bash 

if [ "$(ls -A $DIR1)" ]; then
        echo "moving all photo files to processing directory"
        find $DIR1 -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I{} mv --backup=numbered {} $DIR2;
    else
        echo "directory is empty, skipping"
    fi

if [ "$(ls -A $DIR1)" ]; then
    echo "moving all video files to processing directory"
    find $DIR1 -type f -exec file -N -i -- {} + | sed -n 's!: video/[^:]*$!!p' | cut -d':' -f1 | xargs -I{} mv --backup=numbered {} $DIR3;
else
    echo "directory is empty, skipping"
fi

if [ "$(ls -A $DIR1)" ]; then
    echo "moving all remaining files to manual-review directory"
find $DIR1 -type f -print0 | xargs -0 mv --backup=numbered -t $DIR4;
else
    echo "no remaining files to move, skipping"
fi

스크립트가 예상대로 작동하는 것 같습니다. 몇 달 동안 정기적으로 실행해 보았는데 결과는 예상한 대로였습니다. 그렇긴 하지만, 이를 더 좋게 만드는 방법, 특히 1) 매번 이동된 파일 수를 계산하여 STDOUT으로 인쇄하는 방법, 2) 스크립트가 제대로 작동하는지 확인하기 위해 몇 가지 기본 오류 검사를 추가하는 방법을 찾는 데 도움이 필요합니다. 예상대로 동작합니까?

답변1

이는 스크립트를 개선하려는 시도입니다. 오류 논리를 더 쉽게 추가할 수 있도록 대형 파이프가 제거되었습니다. 또한 계산 논리를 더 쉽게 추가할 수 있습니다. 또한 디렉터리를 세 번 읽지 않고 한 번 읽으므로 속도가 약간 향상될 수 있습니다. 또한 쉘 변수 하위 문자열 제거 및 Case 문(및 다른 매개변수)을 사용하여 잘라내기(및 grep 및 sed) file.

오류 검사의 경우 외부 DIR1/2/3/4 변수를 따옴표로 묶고 이것이 디렉터리의 시작인지 테스트합니다. 저는 Bash FAQ의 null 종료 파일 이름 기술을 사용합니다(여기:http://mywiki.wooledge.org/BashFAQ/020). 이런 일이 발생하면 파일 이름에 공백이 허용됩니다. 물론 mv실패하거나 충돌할 경우 file수행할 작업 과 같이 추가할 수 있는 더 많은 특수 사례가 있습니다.

#!/bin/bash 

if [[ ! -d "$DIR1" || ! -d "$DIR2" || ! -d "$DIR3" || ! -d "$DIR3" ]]; then
    echo "missing environment variables or variables aren't directories" >&2
    exit 1
fi

num_images=0
num_videos=0
num_misc=0

echo STARTING
while IFS= read -r -d $'\0' file; do
   mime=$( file -b --mime-type "$file" )
   case "${mime%%/*}" in
      image)
         output="$DIR2"
         ((num_images++))
        ;;
      video)
         output="$DIR3"
         ((num_videos++))
        ;;
      *)
         output="$DIR4"
         ((num_misc++))
        ;;
    esac
    mv "$file" "$output"
done < <( find "$DIR1" -type f -print0 )

echo FINISHED: moved $num_images images, $num_videos videos, $num_misc other files

관련 정보