Convert Date Formats in Bash

Convert date formats in bash

#since this was yesterday
date -dyesterday +%Y%m%d

#more precise, and more recommended
date -d'27 JUN 2011' +%Y%m%d

#assuming this is similar to yesterdays `date` question from you
date -d'last-monday' +%Y%m%d

#going on @seth's comment you could do this
DATE="27 jun 2011"; date -d"$DATE" +%Y%m%d

#or a method to read it from stdin
read -p " Get date >> " DATE; printf " AS YYYYMMDD format >> %s" `date
-d"$DATE" +%Y%m%d`

#which then outputs the following:
#Get date >> 27 june 2011
#AS YYYYMMDD format >> 20110627

#if you really want to use awk
echo "27 june 2011" | awk '{print "date -d\""$1FS$2FS$3"\" +%Y%m%d"}' | bash

#note | bash just redirects awk's output to the shell to be executed
#FS is field separator, in this case you can use $0 to print the line
#But this is useful if you have more than one date on a line

More on Dates

note this only works on GNU date

I have read that:

Solaris version of date, which is unable
to support -d can be resolve with
replacing version of

Convert date format in bash

If you are using a Unix program, you can often convince it to generate the output in the expected format instead of later trying to process it.

For example, you can do this with git log. Here's what it looks like on a repo:

$ git log --format=%ad --date='format:%Y/%m/%d %H:%M:%S' | head
2021/07/05 22:45:03
2021/07/05 22:20:49
2021/07/05 18:08:33
2021/06/09 11:18:40
2021/05/25 11:48:31
2021/05/21 18:20:40
2021/05/20 17:05:17
2021/05/20 16:53:24
2021/05/20 16:29:13
2021/05/20 16:18:24

This relies on telling git log to format entries to only show the date using --format=%ad and then specifying the format of the date you want using --date='format:%Y/%m/%d %H:%M:%S'. See man git log for more details and man date for the format spacifiers you can use with --date=format:.

YYYY-MM-DD format date in shell script

In bash (>=4.2) it is preferable to use printf's built-in date formatter (part of bash) rather than the external date (usually GNU date).

As such:

# put current date as yyyy-mm-dd in $date
# -1 -> explicit current date, bash >=4.3 defaults to current time if not provided
# -2 -> start time for shell
printf -v date '%(%Y-%m-%d)T\n' -1

# put current date as yyyy-mm-dd HH:MM:SS in $date
printf -v date '%(%Y-%m-%d %H:%M:%S)T\n' -1

# to print directly remove -v flag, as such:
printf '%(%Y-%m-%d)T\n' -1
# -> current date printed to terminal

In bash (<4.2):

# put current date as yyyy-mm-dd in $date
date=$(date '+%Y-%m-%d')

# put current date as yyyy-mm-dd HH:MM:SS in $date
date=$(date '+%Y-%m-%d %H:%M:%S')

# print current date directly
echo $(date '+%Y-%m-%d')

Other available date formats can be viewed from the date man pages (for external non-bash specific command):

man date

Format date in shell script YYYY-MM-DD +DAY + Mounth

Some versions of date can't display the month without the leading zero. You can use sed to remove it, though: the month is the only number surrounded by dashes:

date '+%Y-%m-%d %A %B' | sed 's/-0\([0-9]\)-/-\1-/'

Some versions support the padding modifiers. To turn padding off, use a dash:

date '+%Y-%-m-%d %A %B'

To change the language, just specify the locale:

$ LC_ALL=it_IT.UTF-8 date '+%Y-%m-%d %A %B' | sed 's/-0\([0-9]\)-/-\1-/'
2019-9-17 martedì settembre

How to convert a bash string to date format?

I would expect to use the date command, as you employ it, with a number that represents the number of seconds since the epoch. It seems your number is a formatted date yyyymmddhhmiss.

If you don't need to validate the string that represents a formatted date, then you can use sed to insert extra formatting characters:

echo '20220416124334' | sed -E 's/(....)(..)(..)(..)(..)(..)/\1\/\2\/\3 \4:\5:\6/'

If you end up taking as input a number of seconds since the epoch, then do it this way, keeping in mind that a number means different times in different time zones at different times of the year (eyeroll):

date -u -r 1650113014 "+%Y/%m/%d %H:%M:%S"

Converting date format in bash

To perform only the name transformation, you can use awk:

echo 'backup_2016-30-10_12-00-00' |
awk -F'[_-]' '{ print $1 "_" $3 "-" $4 "-" $2 "_" $5 ":" $6 ":" $7 }'

As fedorqui points out in a comment, awk's printf function may be tidier in this case:

echo 'backup_2016-30-10_12-00-00' |
awk -F'[_-]' '{ printf "%s_%s-%s-%s_%s:%s:%s\n", $1,$3,$4,$2,$5,$6,$7 }'

That said, your specific Linux distro may come with a rename tool that allows you to do the same while performing actual file renaming.

How do I convert a date string in format MMDDYYYY to YYYY-MM-DD at the Unix command line?

String manipulation with variable expansions


Convert date from column in bash

Delimit by ',' -F','.

Skip the first line (NR>1).

Replace - in date string with /, gsub(/-/,"/",$2) so date will recognize the format
as month/day/year.

Convert date format, save as variable d ("date +%Y-%m-%d -d"$2 | getline d).
Then print each field separated by comma.

awk -F',' '(NR>1){gsub(/-/,"/",$2); ("date +%Y-%m-%d -d"$2 | getline d); print $1","d","$3}' file

To skip lines with blank dates, add if($2=="") next; at the start, like this:

awk -F',' '(NR>1){if($2=="") next; gsub(/-/,"/",$2); ("date +%Y-%m-%d -d"$2 | getline d); print $1","d","$3}' file

Related Topics

Leave a reply