파일 이름을 기준으로 디렉터리로 파일을 이동하는 스크립트를 작성 중입니다. 파일에는 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