Bash 스크립트의 이상한 날짜 형식

Bash 스크립트의 이상한 날짜 형식

파일이 생성된 날짜별로 다운로드 폴더를 정렬하는 스크립트를 작성 중입니다. 이것은 내가 사용하고 있는 스크립트입니다:

#!/bin/bash

cd ~/Downloads
for FILENAME in *
do
    if [[ -f $FILENAME ]]; then
        date="$(ls -l $FILENAME | tr -s ' ' | cut -d ' ' -f 6 | tr -d '.')"
        mkdir -vp "$date"
        find . -maxdepth 1 -type f -name $FILENAME -exec mv {} "$date" \;
    fi
done
cd -

이 스크립트로 생성된 폴더의 이름을 보면 Jun어딘가에서 일종의 변환이 진행되고 있다고 믿게 됩니다.

내가 단지

ls -l test0 | tr -s ' ' | cut -d ' ' -f 6 | tr -d '.'

날짜가 19062014올바르게 표시됩니다.

bash -x다음은 스크립트의 결과입니다 .

sigurd@Goliath ~ -> bash -x clean
+ cd /home/sigurd/Downloads
+ for FILENAME in '*'
+ [[ -f test0 ]]
++ ls -l test0
++ tr -s ' '
++ cut -d ' ' -f 6
++ tr -d .
+ date=Jun
+ mkdir -vp Jun
mkdir: created directory 'Jun'
+ find . -maxdepth 1 -type f -name test0 -exec mv '{}' Jun ';'
+ for FILENAME in '*'
+ [[ -f test1 ]]
++ ls -l test1
++ tr -s ' '
++ cut -d ' ' -f 6
++ tr -d .
+ date=Jun
+ mkdir -vp Jun
+ find . -maxdepth 1 -type f -name test1 -exec mv '{}' Jun ';'
+ cd -
/home/sigurd

내가 찾고 있는 기능은 스크립트가 파일이 생성된 시기를 기준으로 이름 등의 19_06_2014폴더 로 파일을 이동해야 한다는 것입니다.20_06_2014

답변1

와 같은 날짜 형식을 사용하는 것이 좋습니다 2014-06-19. 그렇게 하면 ls시간순으로 표시됩니다.

GNU 시스템에서:

#! /bin/bash -
cd ~/Downloads &&
  find . -maxdepth 1 -type f -printf '%p\0%TF\0' |
    while IFS= read -rd '' file && read -d '' date; do
      mkdir -vp "$date" && mv "$file" "$date"
    done

zsh모든 시스템에서 :

#! /bin/zsh -
zmodload zsh/stat || exit

cd ~/Downloads &&
  for file (./*(ND.)) {
    zstat -A date -F %F +mtime $file &&
      mkdir -p $date &&
      mv $file $date
  }

답변2

터무니없는 추측: 명령을 대화형으로 시도할 때 사용되는 별칭이 있는데 ls해당 별칭은 스크립트에서 사용되지 않습니다. 아마도 이런 것일까요?

alias ls="ls --full-time"

일반적인 통념에 따르면 구문 분석을 시도하는 것은 ls나쁜 생각입니다. Linux 시스템을 사용한다고 가정하면 다음과 같은 것이 바람직할 수 있습니다.

stat "$FILENAME" | awk '/^Modify: /{print $2}'

편집: 또는 Stéphane이 아래에서 지적했듯이 findwith를 사용하는 -printf것이 더 좋습니다. 의 출력은 stat보다 예측하기가 약간 쉽지만 ls사용자 -printf가 완전히 제어할 수 있는 출력 형식을 허용합니다.

답변3

전체 코드는 다음과 같습니다.

#!/bin/bash
cd ~/Downloads
for FILENAME in $(find . -maxdepth 1 -type f); do    
    DATE=$(stat "$FILENAME" | awk '/^Modify: /{print $2}')
    [ ! -d "$DATE" ] && mkdir -vp "$DATE"

    mv "$FILENAME" "${DATE}/$FILENAME"
done
cd -

관련 정보