是否有一个简单的 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]
}
阅读评论作为解释。
我使用月份的全名,您可能需要将其更改为缩写。