ファイル名を変更して日付スタンプを '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次のファイル名の日付文字列を一致させます(ファイル名と説明は可変長文字列です)...次のファイル名に変換できる単純なbashコマンドはありますか File_Name_20190520_descr.txt

日付ベースのファイル名変換について議論する他のいくつかの質問があることはわかっていますが、Perlに関連しているか、序数指定子(1st、2nd、3rd、4th)について特に言及していません。

答え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文字、あるいは、、th2nd文字の長さであると予想することはできないため、rd調整が必要な場合があります。

答え2

奇妙な:

{
    # 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]
}

説明を見るにはコメントを読んでください。

月のフルネームを使用しました。略語に変更する必要があります。

関連情報