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 -

관련 정보