"cut"과 "rev"를 사용하는 현재 방법보다 파일 이름에서 연도를 추출하여 연도 기반 디렉터리로 이동하는 더 빠른 방법은 무엇입니까?

"cut"과 "rev"를 사용하는 현재 방법보다 파일 이름에서 연도를 추출하여 연도 기반 디렉터리로 이동하는 더 빠른 방법은 무엇입니까?

일부 파일을 얻기 위해 Linux를 실행하는 원격 저장소에 액세스하는 웹 응용 프로그램이 있습니다. 문제는 원격 저장소에 현재 300만 개의 파일이 있으므로 일반적인 액세스 방법이 약간 까다롭다는 것입니다.

그래서 생성 날짜와 특히 이름을 기준으로 파일을 여러 폴더로 재구성하는 스크립트를 더 쉽게 사용할 수 있도록 작성해야 합니다. 이 스크립트를 만들었고 정상적으로 작동합니다. 원래 의도한 대로 작동했습니다. , 하지만 속도가 너무 느려서 12시간 안에 완료할 수 없었습니다 (12:13:48 to be precise).

속도가 느린 것은 내가 여러 번 전화를 걸었기 때문인 것 같습니다 cut.rev


:

ls명령과 함께 for 루프를 사용하여 파일 이름을 가져오고 각 파일에 대해 상위 디렉터리를 가져오고 상위 디렉터리를 기반으로 올바른 연도를 가져올 수 있습니다.

 case "$parent" in
                ( "Type1" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 2 | rev );;

                ( "Type2" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 2 | rev);;

                ( "Type3" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;

                ( "Type4" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;

                ( "Type5" )
                year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;
                esac

~을 위한유형 1파일 수:

the file==>MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf

역전단을 수행하려면 연도를 가져와야 합니다.

year=$(echo "$file" | rev | cut -d '_' -f 2 | rev );;

~을 위한유형 2파일 수:

the file==>MY_AMAZING_FILE_THAT_IMADE_IN_YEAR_WITH_TY.pdf 

등...

mv그런 다음 파일을 자유롭게 사용할 수 있습니다 .mv $file /some/path/destination/$year/$parent

그러나 이것은 가장 간단한 예입니다. 일부 파일은 훨씬 더 복잡하므로 1개의 정보를 얻으려면 4개의 작업을 수행해야 합니다 1 echo , 2rev and 1echo.

스크립트가 실행될 때 내 속도는 50 files/sec to 100 files\s스크립트를 실행하여 이 정보를 얻습니다.wc-l output.txt


더 빠르게 할 수 있는 방법이 있나요? 아니면 파일 이름을 자르는 다른 방법이 있나요? sedOR 또는 문자열 조작을 사용할 수 있다는 것을 알고 있지만 awk실제로 어떻게 사용하는지 이해하지 못합니다.

답변1

외부 유틸리티를 사용하지 않고 YEAR파일 이름의 일부를 얻으려면 다음을 수행하십시오.MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf

name='MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf'

year=${name%_*}    # remove everything after the last '_'
year=${year##*_}   # remove everything up to the last (remaining) '_'

질문을 업데이트한 후:

아래에서 PDF 파일을 파일 이름에 연도가 포함되고 파일 이 위치한 원래 디렉터리의 기본 이름인 topdir디렉터리로 이동합니다./some/path/destination/<year>/<parent><year><parent>

find topdir -type f -name '*.pdf' -exec bash ./movefiles.sh {} +

movefiles.sh현재 디렉토리에 쉘 스크립트가 있습니까?

#!/bin/bash

destdir='/some/path/destination'

for name; do
    # get basename of directory
    parent=${name%/*}
    parent=${parent##*/}

    # get the year from the filename:
    #  - Pattern:  _YYYY_         (in the middle somewhere)
    #  - Pattern:  _YYYYMMDD.pdf  (at end)
    if [[ "$name" =~ _([0-9]{4})_ ]] ||
       [[ "$name" =~ _([0-9]{4})[0-9]{4}\.pdf$ ]]; then
        year="${BASH_REMATCH[1]}"
    else
        printf 'No year in filename "%s"\n' "$name" >&2
        continue
    fi

    # make destination directory if needed
    # (remove echo when you have tested this at least once)
    if [ ! -d "$destdir/$year/$parent" ]; then
        echo mkdir -p "$destdir/$year/$parent"
    fi

    # move file
    # (remove echo when you have tested this at least once)
    echo mv "$name" "$destdir/$year/$parent"
done

답변2

당신은 신청할 수 있습니다sed추출방법년도값:

year=$(sed -E 's/.*_([0-9]{4})_TY\.pdf/\1/' <<<"$file")

관련 정보