1

Is there a simple bash command that will match the date string in a filename like this... File Name 20th May 2019 descr.txt (File Name and descr are strings of variable length) ...and convert it to a filename like this: File_Name_20190520_descr.txt ?

I know there are some other questions that discuss date-based filename conversions but they are either related to Perl or don't specifically mention the ordinal indicator (1st, 2nd, 3rd, 4th).

0

2 Answers 2

1

With 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// /_}' 

Remove the -n when happy.

That's if the month is the 3 character abbreviation. If it's the full name:

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// /_}' 

Those assume the file names are in the language of the current locale. If the month names are always in English, you can set LC_ALL=C. In any case, where te language is not English, you can't necessarily expect the abbreviations to always be 3 characters long or the th, nd, rd to be two characters long, so you'd probably need to adapt.

0

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

Read comment as explanation.

I use full name of month, you might need to change it to abbreviation.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.