convert date string with hour and minutes to seconds in bash - bash

I have a sample string that contains YYYYMMDDHHMM format.
I am trying to convert it into seconds but getting below error.
[vagrant#CentOS-Seven ~]$ export SAMPLE_DATE=201812051147
[vagrant#CentOS-Seven ~]$ echo $SAMPLE_DATE
201812051147
[vagrant#CentOS-Seven ~]$ date -d $SAMPLE_DATE
date: invalid date ‘201812051147’
[vagrant#CentOS-Seven ~]$

According to this answer date has not option to specify the input format. Therefore you have to convert your input into a format that is accepted by date. The sed command in the following command converts 201812051147 to 2018-12-05 11:47.
To convert a date to seconds, use the output format +%s.
$ input=201812051147
$ date -d "$(sed -E 's/(....)(..)(..)(..)(..)/\1-\2-\3 \4:\5/' <<< "$input")" +%s
1544010420
Please not that the output depends on your systems timezone. You can change the timezone by setting the TZ environment variable.
By the way: You don't have to export your variable in this case. Also, the convention for naming variables in bash is to use lowercase letters. By convention only special variables are written in all caps. Using variable names written in all caps could lead to a name collisions with these variables.

Apparently separating date and time parts with a space is enough, so:
$ echo 201812051147 |
sed -E 's/(.{8})(.{4})/\1 \2/' |
date -f - +"%s"
Output:
1544003220

You can use the "touch" command to assign that date to a file and then print it using "date", try this:
touch -t 201812051147 tmpfile ; date -r tmpfile +%s ; rm -f tmpfile

Related

How to convert normal text into date format in bash shell?

I want to convert it from
Format 1: 12272019(this is just a number)
To
Format 2: 2019-12-27
I tried using below:
date -d '12272019' +%Y-%m-%d
But it is showing invalid date format
The date command only accepts a predefined set of formats for its input. Your format mmddyyyy is not part of that set.
You can re-arrange your date string manually using either sed:
sed -E 's/(..)(..)(....)/\3-\1-\2/' <<< 12272019
or bash:
date=12272019
echo "${date:4}-${date:0:2}-${date:2:2}"
On OS/X, date is quite a bit different, so you can specify the input format for date:
date -jf "%m%d%Y" 12272019 +"%Y-%m-%d"
# => 2019-12-27
Linux does not allow you to do that though, but you can do it easily with sed:
echo 12272019 | sed -e 's/\(..\)\(..\)\(....\)/\3-\1-\2/'
# => 2019-12-27

How to get formatted date twice, ensuring it's the same time?

I have a Bash script which uses:
THE_DATE=`date +"%Y-%m-%d-%H%M%S"`
To get the current date and time in a format which can be used to mkdir new directory.
But, for report generation, I use something like:
REPORT_DATE=`date +"%Y-%m-%d %H:%M:%S"`
Which is the same, but different, if you see what I mean.
This means running date twice, and I understand that it's possible (although unlikely) for the seconds component to different between the two.
How, do I get the date in two different formats at the same time?
Get the date in a well-known format, and then pass it to date (using -d):
date="$(date +%s)"
the_date="$(date +'%Y-%m-%d-%H%M%S' -d "#${date}")"
report_date="$(date +'%Y-%m-%d %H:%M:%S' -d "#${date}")"
%s gets us the time in Unix time, which we can later use to make date print a specific time, instead of the current. The # prefix gives date a hint of the format.
It's possible that some other format could be used, but Unix time seemed the most universal and least error-prone.
(Off-topic: Don't use uppercase variable names, and use $() instead of backticks.)
You can call date only once, separating both dates by a newline (or other character) and read them:
IFS=$'\n' read -d '' -r the_date report_date < <(date +"%Y-%m-%d-%H%M%S%n%Y-%m-%d %H:%M:%S"; printf '\0')
or, similarly but with two calls to read:
{ read -r the_date; read -r report_date; } < <(date +"%Y-%m-%d-%H%M%S%n%Y-%m-%d %H:%M:%S")
So, basically, my answer is about calling date only once, and parsing its output…
As a side-note, since Bash 4.2, you can use the builtin printf instead of the external date:
{ read -r the_date; read -r report_date; } < <(printf "%(%Y-%m-%d-%H%M%S%n%Y-%m-%d %H:%M:%S)T\n" -1)
REPORT_DATE="$(date +"%Y-%m-%d %H:%M:%S")"
# Edit: Incorrect and slow: THE_DATE="$(echo "${REPORT_DATE}" | tr -d ":")
THE_DATE="$(echo "${REPORT_DATE//:}" | tr -d " " "-")"

Getting the creation date of a file on Cygwin

I'm trying to get the creation date of a file using console commands. I've managed to use this:
stat -c "%w" file
which outputs the date and time:
2015-05-01 09:33:22.503525000 -0400
But I'd like to extract only the date (without the time) from the result. Is there a way to do this using only stat, or do I have to separate the result using another command? And what might that command be?
Try this:
stat -c "%w" file | cut -d" " -f1
The output of stat will be piped into cut and the string will be cut at the first concurrence of a white space.
Assuming you are using bash:
date -d "#$(stat -c %W file)" +%F
Will do the trick. %W on stat returns the epoch date, date +%F converts it to a YYYY-MM-DD format.

how to convert hh:mm:ss into hhmmss for single data input using shell

I have time in format hh:mm:ss in a variable and I need to change it in hhmmss format for processing using shell script.
eg.
time=12:12:10 and I want it in variable new_time in format 121210.
Please suggest command.
bash simply:
time=12:12:10
echo ${time//:}
121210
Using tr:
t='12:12:10'
echo "$t" | tr -d ':'
121210
you can use sed command
m='12:12:10'
echo "$m"|sed 's/\://g'
output will be
121210

Shell Script String Manipulation

I'm trying to replace an epoch timestamp within a string, with a human readable timestamp. I know how to convert the epoch to the time format I need (and have been doing so manually), though I'm having trouble figuring out how to replace it within the string (via script).
The string is a file name, such as XXXX-XXX-2011-01-25-3.6.2-record.pb.1296066338.gz (epoch is bolded).
I've been converting the timestamp with the following gawk code:
gawk 'BEGIN{print strftime("%Y%m%d.%k%M",1296243507)}'
I'm generally unfamiliar with bash scripting. Can anyone give me a nudge in the right direction?
thanks.
You can use this
date -d '#1296066338' +'%Y%m%d.%k%M'
in case you don't want to invoke awk.
Are all filenames the same format? Specifically, "." + epoch + ".gz"?
If so, you can use a number of different routes. Here's one with sed:
$ echo "XXXX-XXX-2011-01-25-3.6.2-record.pb.1296066338.gz" | sed 's/.*\.\([0-9]\+\)\.gz/\1/'
1296066338
So that extracts the epoch, then send it to your gawk command. Something like:
#!/bin/bash
...
epoch=$( echo "XXXX-XXX-2011-01-25-3.6.2-record.pb.1296066338.gz" | sed 's/.*\.\([0-9]\+\)\.gz/\1/' )
readable_timestamp=$( gawk "BEGIN{print strftime(\"%Y%m%d.%k%M\",${epoch})}" )
Then use whatever method you want to replace the number in the filename. You can send it through sed again, but instead of saving the epoch, you would want to save the other parts of the filename.
EDIT:
For good measure, a working sample on my machine:
#!/bin/bash
filename="XXXX-XXX-2011-01-25-3.6.2-record.pb.1296066338.gz"
epoch=$( echo ${filename} | sed 's/.*\.\([0-9]\+\)\.gz/\1/' )
readable_timestamp=$( gawk "BEGIN{print strftime(\"%Y%m%d.%k%M\",${epoch})}" )
new_filename=$( echo ${filename} | sed "s/\(.*\.\)[0-9]\+\(\.gz\)/\1${readable_timestamp}\2/" )
echo ${new_filename}
You can use Bash's string manipulation and AWK's variable passing to avoid having to make any calls to sed or do any quote escaping.
#!/bin/bash
file='XXXX-XXX-2011-01-25-3.6.2-record.pb.1296066338.gz'
base=${file%.*.*} # XXXX-XXX-2011-01-25-3.6.2-record.pb
epoch=${file#$base} # 1296066338.gz
epoch=${epoch%.*} # 1296066338
# we can extract the extension similarly, unless it's safe to assume it's ".gz"
humantime=$(gawk -v "epoch=$epoch" 'BEGIN{print strftime("%Y%m%d.%k%M",epoch)}')
newname=$base.$humantime.gz
echo "$newname"
Result:
XXXX-XXX-2011-01-25-3.6.2-record.pb.20110126.1225.gz

Resources