배치 파일은 파일 이름을 기준으로 디렉터리 구조로 이동합니다.

배치 파일은 파일 이름을 기준으로 디렉터리 구조로 이동합니다.

파일 이름을 기준으로 디렉터리로 파일을 이동하는 스크립트를 작성 중입니다. 파일에는 yyyyddmm-xxxxxxx.jpg이름 형식이 있습니다 . 필수 디렉토리 구조는 다음 형식을 따릅니다 2013/01 Jan/31. date월 번호와 월 이름 사이의 공백 형식을 올바르게 지정할 수 없습니다 . +%Y/%m %b형식을 사용하려고 하면 다음과 같은 오류 메시지가 나타납니다.

날짜: 추가 피연산자 `%b"'

나는 큰 따옴표와 작은 따옴표를 시도했지만 성공하지 못했습니다. 그러나 date +"%Y/%m %b/%d"다음과 같은 상황에서는 제대로 작동합니다 sh.

2013년 10월 27일

MOVEDIRSTR또한 변수를 사용하는 것보다 디렉토리 이름을 생성하는 더 좋은 방법이 있습니까 MOVEDIR(스크립트 참조)?

이것은 내 현재 스크립트입니다.

FLIST=`ls "$IMGDIR" | grep -E '^.*\.jpg$'`

# If there are files to move
if [ -n "${FLIST}" ]; then
    # For each file
    while read -r line; do
        # Parse filename to YYYY/mm Mmm/Dd
        echo $line
        MOVEDIRSTR=`sed -r -e 's:([0-9]{4})([0-9]{2})([0-9]{2}).*:date -d \1-\2-\3 +%Y/%m_%b/%d:' <<< "$line"`
        MOVEDIR=`$MOVEDIRSTR`

        # If a directory does not exist, create it
        [ -d "$ARCHIVEDIR/$MOVEDIR" ] || (mkdir -p "$ARCHIVEDIR/$MOVEDIR")

        # Move file into YYYY/mm Mmm directory
        # mv -f "$IMGDIR/$line" "$ARCHIVEDIR/$MOVEDIR"
    done <<< "$FLIST"
fi

답변1

+기호 뒤에는 날짜 형식을 인용 해야 합니다 .

$ date +"%Y/%m %b"
2013/10 Oct

변수에 대하여. $MOVEDIRSTR불필요한 것 같습니다.

MOVEDIR=$(sed -r -e 's:([0-9]{4})([0-9]{2})([0-9]{2}).*:date -d \1-\2-\3 +%Y/%m_%b/%d:' <<< "$line")

해당 디렉토리의 날짜를 구문 분석하고 있으므로 $FLIST더 깔끔한 방법이 보이지 않습니다.

업데이트 #1

아래 설명에 있는 OP의 피드백을 고려하면 그는 QNAP 장치를 사용하고 있으므로 BusyBox에서 제공하는 이러한 명령의 버전을 약화시켰을 가능성이 높습니다. date 명령을 다음과 같이 보면 ls -l /bin/date아마도 busybox 또는 이와 유사한 실행 파일에 대한 링크일 것입니다. 이러한 명령은 완전히 작동하지 않으므로 문제가 발생합니다.

그는 다음과 같이 확인했습니다.

당신 말이 맞을 수도 있습니다. 내 날짜는 자체 실행 파일이지만 /bin/sed -> busybox

이러한 제한 사항으로 인해 기능이 제한된 도구를 사용하고 있으므로 위의 방법이 작동하지 않을 수 있습니다.

답변2

먼저, 나는 글로브를 사용하여 피하기 위해ls를 구문 분석하다.jpg이 로터리 방식으로 파일 목록을 가져옵니다. 둘째, 셸 자체(필수 아님 sed)를 사용하여 날짜 부분을 추출할 수 있습니다.

shopt -s nullglob
for file in "$IMGDIR"/*.jpg; do
    file_name="$(basename file)"
    printf "%s\n" "$file_name"
    numbers="${file%-*}"
    year="${numbers%[0-9][0-9][0-9][0-9]}"
    monthday="${numbers#[0-9][0-9][0-9][0-9]}"
    month="${monthday%[0-9][0-9]}"
    day="${monthday#[0-9][0-9]}"
    movedir="$(date -d "$year-$month-$day" +"%Y/%m %b/)"
    movefile="$(date -d "$year-$month-$day" +"%Y/%m %b/%d)"
    [ -d "$ARCHIVEDIR/$movedir" ] || mkdir -p "$ARCHIVEDIR/$movedir"
    mv "$file" "$movefile"
done

물론 date이는 BusyBox와 별도의 실행 파일이라고 언급했기 때문에 명령에 완전한 기능 세트가 있다고 가정합니다. 날짜 문자열의 길이가 정확히 8자리가 아닌 경우에도 중단됩니다.

답변3

다음이 날짜 추출 및 형식 지정 부분을 해결하는지 확인하십시오.

$ f=20130131-abcdefgh.jpg
$ [[ $f =~ ^([[:digit:]]{4})([[:digit:]]{2})([[:digit:]]{2}) ]]
$ yyyy=${BASH_REMATCH[1]}
$ mm=${BASH_REMATCH[2]}
$ dd=${BASH_REMATCH[3]}
$ date -d ${yyyy}-${mm}-${dd} +'%Y/%m %b/%d'
2013/01 Jan/31

관련 정보