파일 이름 끝에 날짜가 수정 된 타임 스탬프가있는 여러 파일의 이름을 바꾸시겠습니까? 20 일에

따라서 g.txt와 같은 많은 파일이있는 디렉토리가 있습니다 .g.txt는 마지막으로 2012 년 6 월 20 일에 수정되었습니다.

마지막 수정 날짜가 2012 년 6 월 20 일 끝에 추가 된 모든 파일 (g.txt 등)을 일괄 이름을 바꾸려면 어떻게해야합니까?



답변

빠르고 더러운 Bash one-liner를 사용하여 현재 디렉토리의 모든 (글로브 된) 파일 이름 filename.txtfilename.txt-20120620다음에서

for f in *; do mv -- "$f" "$f-$(stat -c %Y "$f" | date +%Y%m%d)"; done

진취적인 Bash 머저리가 그것을 깨뜨릴 수있는 최첨단 사례를 발견 할 것입니다. 🙂

분명히 이것은 파일 끝에 이미 날짜처럼 보이는 것이 있는지 확인하는 것과 같은 바람직한 일을하지 않습니다.


답변

다음은 goldschrafe의 단일 라이너 버전입니다.

  • 통계를 사용하지 않습니다
  • 이전 버전의 GNU 날짜에서 작동
  • 파일 이름의 공백에 올바르게 대처하십시오.
  • 대시로 시작하는 파일 이름에도 대응

    for f in *; do mv -- "$f" "$f-$(date -r "$f" +%Y%m%d)"; done


답변

필수 zsh one-liner (선택적 구성 요소의 일회성로드는 계산하지 않음) :

zmodload zsh/stat
autoload -U zmv
zmv -n '(*)' '$1-$(stat -F %Y%m%d +mtime -- $1)'

우리 statzsh/stat모듈 의 내장 zmv기능 과 파일 이름 바꾸기 기능을 사용합니다. 그리고 여기에 연장 전에 날짜를 두는 여분의 것이 있습니다.

zmv -n '(*)' '$1:r-$(stat -F %Y%m%d +mtime -- $1)${${1:e}:+.$1:e}'

답변

이해했듯이 수정 날짜가 무엇인지 미리 알 수 없습니다. 따라서 각 파일에서 가져 와서 출력 형식을 지정하고 파일 이름에 수정 날짜가 포함되도록 각 파일의 이름을 바꾸어야합니다.

이 스크립트를 “modif_date.sh”와 같은 이름으로 저장하여 실행 가능하게 만들 수 있습니다. 대상 디렉토리를 인수로 사용하여 호출합니다.

modif_date.sh txt_collection

여기서 “txt_collection”은 이름을 바꾸려는 모든 파일이있는 디렉토리의 이름입니다.

#!/bin/sh

# Override any locale setting to get known month names
export LC_ALL=c
# First we check for the argument
if [ -z "$1" ]; then
    echo "Usage: $0 directory"
    exit 1
fi

# Here we check if the argument is an absolute or relative path. It works both ways
case "${1}" in
  /*) work_dir=${1};;
  *) work_dir=${PWD}/${1};;
esac

# We need a for loop to treat file by file inside our target directory
for i in *; do
    # If the modification date is in the same year, "ls -l" shows us the timestamp.
    # So in this case we use our current year.
    test_year=`ls -Ggl "${work_dir}/${i}" | awk '{ print $6 }'`
    case ${test_year} in *:*)
        modif_year=`date '+%Y'`
        ;;
    *)
        modif_year=${test_year}
        ;;
    esac
    # The month output from "ls -l" is in short names. We convert it to numbers.
    name_month=`ls -Ggl "${work_dir}/${i}" | awk '{ print $4 }'`
    case ${name_month} in
            Jan) num_month=01 ;;
            Feb) num_month=02 ;;
        Mar) num_month=03 ;;
        Apr) num_month=04 ;;
        May) num_month=05 ;;
        Jun) num_month=06 ;;
        Jul) num_month=07 ;;
        Aug) num_month=08 ;;
        Sep) num_month=09 ;;
        Oct) num_month=10 ;;
        Nov) num_month=11 ;;
        Dec) num_month=12 ;;
        *) echo "ERROR!"; exit 1 ;;
    esac
    # Here is the date we will use for each file
    modif_date=`ls -Ggl "${work_dir}/${i}" | awk '{ print $5 }'`${num_month}${modif_year}
    # And finally, here we actually rename each file to include
    # the last modification date as part of the filename.
    mv "${work_dir}/${i}" "${work_dir}/${i}-${modif_date}"
done

답변

다음은 CAS의 oneliner의 버전 (goldschrafe의 oneliner 기준)이다는로 확장 멱등 ,

즉, 날짜 시간이 붙은 파일을 접두어로 확장하고 아직 날짜 시간 접두사가없는 파일에 대해서만이를 수행 하도록 확장되었습니다 .

유스 케이스 : 디렉토리에 새 파일을 추가하고 아직없는 파일에 날짜 시간 접 두부를 추가하려는 경우에 유용합니다.

for f in * ; do
  if [[ "$f" != ????-??-??' '??:??:??' - '* ]]; then
    mv -v -- "$f" "$(date -r "$f" +%Y-%m-%d' '%H:%M:%S) - $f" ;
  fi;
done