Bash 命令重命名文件并将日期戳从 'dd[st/nd/rd/th] mmm yyyy' 转换为 'yyyymmdd'?

Bash 命令重命名文件并将日期戳从 'dd[st/nd/rd/th] mmm yyyy' 转换为 'yyyymmdd'?

是否有一个简单的 bash 命令可以匹配这样的文件名中的日期字符串... File Name 20th May 2019 descr.txt(文件名和 descr 是可变长度的字符串)...并将其转换为这样的文件名: File_Name_20190520_descr.txt

我知道还有一些其他问题讨论基于日期的文件名转换,但它们要么与 Perl 有关,要么没有具体提及序数指示符(第 1、第 2、第 3、第 4)。

答案1

zsh

zmodload zsh/datetime
autoload zmv
zmv -n '(* )(<1-31>)??( ??? <1900-2100>)( *.txt)' \
  '${1// /_}$(strftime %Y%m%d "$(strftime -r "%d %b %Y" $2$3)")${4// /_}'

高兴的时候去掉-n

如果月份是 3 个字符的缩写。如果是全名:

zmodload zsh/datetime
zmodload zsh/langinfo
autoload zmv
zmv -n '(* )(<1-31>)?? ('${(vj:|:)langinfo[(I)MON_*]}')( <1900-2100>)( *.txt)' \
  '${1// /_}$(strftime %Y%m%d "$(strftime -r "%d %B %Y" $2$3$4)")${5// /_}'

这些假定文件名采用当前语言环境的语言。如果月份名称始终为英文,则可以设置LC_ALL=C。无论如何,如果语言不是英语,您不一定期望缩写始终为 3 个字符长,或者th, nd,rd为两个字符长,因此您可能需要进行调整。

答案2

awk:

{
    # split by date
    split($0, a, /[0-9]{1,2}[a-z]{2} +(January|February|March|April|May|June|July|August|September|October|November|December) +[0-9]{4}/, seps)
    # remove trailing nth from day
    sub(/[a-z]{2}/, "", seps[1])
    # get desired date format from shell command
    "date -d '" seps[1] "' +%Y%m%d" | getline d
    # replace space with _
    gsub(/ +/, "_", a[1])
    gsub(/ +/, "_", a[2])
    print a[1] d a[2]
}

阅读评论作为解释。

我使用月份的全名,您可能需要将其更改为缩写。

相关内容