파일 이름 끝에 날짜 수정 타임스탬프가 포함된 여러 파일의 이름을 바꾸시나요?

파일 이름 끝에 날짜 수정 타임스탬프가 포함된 여러 파일의 이름을 바꾸시나요?

예를 들어, g.txt와 같은 파일이 많이 포함된 디렉터리가 있는데, 여기서 g.txt는 2012년 6월 20일에 마지막으로 수정되었습니다.

마지막 수정 날짜인 2012년 6월 20일을 끝에 추가하여 모든 파일(예: g.txt)의 이름을 일괄적으로 바꾸려면 어떻게 해야 합니까?

답변1

다음은 goldschrafe의 한 줄짜리 버전입니다.

  • 스텟을 사용하지 않습니다

  • 이전 버전의 GNU 날짜와 작동합니다.

  • 파일 이름의 공백을 올바르게 처리합니다.

  • 대시로 시작하는 파일 이름에도 대응합니다.

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


업데이트 2021-03-20

이 질문에 대한 내 대답은 수년 동안 나를 괴롭혔습니다(글쎄, 내가 그것을 기억할 때만 – 오늘처럼 또 다른 찬성표를 받는 날에). 그래서 마침내 업데이트하게 되었습니다. 위의 원래 답변은 여전히 ​​​​작동하지만 아래의 업데이트 된 답변이 더 좋습니다.

좋다어느배치 파일 이름 바꾸기 작업은 다음과 같이 수행되어야 합니다. rename루프에 대한 일부 투박한 쉘이 아닌 유틸리티입니다.

s/search/replace/Perl 이름 바꾸기 유틸리티는 간단한 정규식 작업(대부분의 이름 바꾸기 작업에 충분함) 부터 복잡한 여러 줄 스크립트에 이르기까지 모든 Perl 코드를 사용하여 파일 이름을 바꿀 수 있게 해주는 특수한 스크립트 언어입니다 .

예를 들어

rename -n 'BEGIN {use Date::Format};
           die $! unless -f $_;
           next if (m/-\d{8}$/);
           my $ts=(stat($_))[9];
           my $dt=time2str("%Y%m%d",$ts);
           s/$/-$dt/;' *.txt

여기에는 Perl과 Date::Format모듈(Perl이 있는 모든 시스템에 설치해야 할 정도로 유용한 모듈)만 필요합니다. IMO에서는 저자 Graham Barr의 Date::Parse모듈 과 함께~해야 한다Perl의 핵심 모듈 라이브러리의 일부가 되어야 하지만 그렇지 않기 때문에 cpan데비안 libtimedate-perl패키지와 같은 배포판 패키지를 사용하여 설치해야 합니다.

그런데, 이 스크립트는 파일 이름 끝에 이미 날짜(예: 8자리)가 있는 것처럼 보이는 모든 파일을 건너뜁니다.

또는 파일 접미사(있는 경우) 앞에 날짜를 넣는 더 멋진 버전의 경우:

rename -n 'BEGIN {use Date::Format; use File::Basename};
           die $! unless -f $_;
           my ($filename,$dirs,$suffix) = fileparse($_,qr/\.[^.]*/);
           next if (m/-\d{8}${suffix}$/);
           my $ts=(stat($_))[9];
           my $dt=time2str("%Y%m%d",$ts);
           s/${suffix}$/-${dt}${suffix}/;' *.txt

File::Basename이 버전 에는 제가 기억하는 한(최소 10년, 아마도 그 이상) 모듈이 Perl의 표준 코어 모듈로 포함되어 있었기 때문에 추가 요구 사항이 없습니다 .

메모:위의 두 rename스크립트 모두 결과를 적용하기 전에 테스트/시뮬레이션할 수 있도록 이름 바꾸기 -n(일명 )의 "dry-run" 옵션을 사용합니다. 원하는 작업이 수행되는 것이 확실하면 --nono제거 -n(또는 자세한 출력을 위한 것으로 교체 )하십시오.-v

또한 참고:다른 Perl rename스크립트와 마찬가지로 명령줄 및/또는 표준 입력에서 제공된 파일 이름을 바꿀 수 있습니다. 예를 들어 현재 디렉터리와 모든 하위 디렉터리에 있는 모든 .txt 파일의 이름을 바꾸려면 다음을 수행하세요.

find . -type f -iname '*.txt' -print0 | 
   rename -0 --nofullpath -n '..........'

그런데 여기서는 발견된 파일 경로 중 파일 이름 부분만 이름을 바꾸도록 하기 위해 rename--nofullpath(일명 -d, --filenmame, ) 옵션을 사용했습니다 . --nopath이 특별한 경우에는 필요하지 않지만(예제 이름 바꾸기 스크립트는 파일 이름의 끝만 변경하기 때문에) 일반적으로 경로와 파일 이름의 이름을 바꾸고 싶지 않을 때(예: 's/ //g'제거하려는 이름 바꾸기 스크립트) 사용하는 것이 좋습니다. spaces from filenames 는 경로에 있는 공백과 가 없는 파일 이름을 제거하려고 시도하므로 --nofullpath오류가 발생하여 실패할 수 있습니다.

마지막으로:Perl 이름 바꾸기 스크립트( 또는 Fedora 및 RedHat에서 File::Rename때때로 호출됨 )를 이름 바꾸기라는 다른 프로그램과 혼동하지 마십시오. prenameperl-rename오직이 Perl 기반 이름 바꾸기 유틸리티는 위에 표시된 것처럼 임의의 Perl 코드를 사용하여 파일 이름을 바꿀 수 있습니다. 다른 이름 바꾸기 유틸리티는 다른 기능과 서로 다르고 호환되지 않는 명령줄 옵션을 갖습니다.

올바른 이름 바꾸기가 설치되어 있는지 확인할 수 있습니다.

$ rename -V
/usr/bin/rename using File::Rename version 1.13, File::Rename::Options version 1.10

실행 파일은 시스템에서 호출될 수 있으므로 해당 실행 파일을 사용해 보고 위 prename의 예를 조정하여 올바른 실행 파일 이름을 사용하십시오.perl-renamefile-rename-V

답변2

filename.txt현재 디렉토리의 모든 (글로브된) 파일 이름을 다음 에서 다음으로 바꾸는 빠르고 더러운 Bash 한 줄입니다 filename.txt-20120620.

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

진취적인 Bash 괴짜라면 이를 깨뜨릴 수 있는 극단적인 사례를 찾을 것이라고 확신합니다. :)

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

답변3

필수 zsh 단일 라이너(선택적 구성 요소의 일회성 로드는 계산하지 않음):

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

stat우리 는zsh/stat기준 치수, 그리고zmv파일 이름을 바꾸는 기능. 그리고 연장 날짜 앞에 날짜를 추가하는 추가 항목이 있습니다.

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

답변4

다음은 cas의 one-liner 버전입니다(goldschrafe의 oneliner 기반).멱등성,

즉, 날짜 시간과 접두사 파일로 확장됩니다.아직 날짜 시간 접두어가 없는 사람들에게만 이 작업을 수행하려면.

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

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

관련 정보