how can i convert "System uptime: 2 days, 9 hours, 16 minutes, 5 seconds" to a bash date?
I want to compare this date with another one.
Thx in advance.
how can i convert "System uptime: 2 days, 9 hours, 16 minutes, 5 seconds" to a bash date?
I want to compare this date with another one.
Thx in advance.
Assuming that the message will always include all the date components at fixed places, Unix timestamp (seconds past epoch) can be calculated using.
# Set t from command, or file.
t="System uptime: 2 days, 9 hours, 16 minutes, 5 seconds"
# Split into words
read -a p <<< "$t"
# Uptime in seconds
uptime=$((p[2]*24*60*60+p[4]*60*60+p[6]*60+p[8]))
now=$(date '+%s')
up_ts=$((now-uptime))
echo "Timestamp: $up_ts"
# Convert to human readable date.
up_date=$(date +'%Y-%m-%d %H:%M:%S' -d "@$up_ts")
echo "Date: $up_date"
You can also use bash built-in date formatting on the 'up_ts'.
If the format of the uptime message depends on the values (e.g., days is not included if uptime < 1 day), additional parsing will be needed.
Here you find a robust way that will convert your duration into the total number of seconds. This is robust as it does not need to have all the quantities listed. I.e. the output can be any of the following:
System uptime: 16 minutes, 2 seconds
System uptime: 12 days, 3 seconds
System uptime: 15minutes,12hours
Create a file convert.awk
which contains
BEGIN { a["seconds"]=1; a["minutes"]=60
a["hours"]=3600; a["days"]=86400;
a["weeks"]=7*86400 }
{ tmp=tolower($0) }
{ while (match(tmp,/[0-9]+[^a-z]*[a-z]+/)) {
u=substr(tmp,RSTART,RLENGTH); q=u+0; gsub(/[^a-z]/,"",u)
t+=q*a[u]
tmp=substr(tmp,RSTART+RLENGTH)
}
print t
}
Run the following command:
$ echo "System uptime: 2 days, 9 hours, 16 minutes, 5 seconds" | awk -f convert.awk
206165
$ echo "System uptime: 2 weeks, 9 days, 16 minutes, 5 seconds" | awk -f convert.awk
1988165
How does this work:
When we read a line, eg.
tmp="system uptime: 16 minutes, 2 seconds"
The match
command will search for any substring which starts with numbers and ends with a character string. match
will automatically set the variables RSTART
and RLENGTH
to the position of the found substring and the length of it. This way, the command u=substr(tmp,RSTART,RLENGTH)
will set
u="16 minutes"
You can now just do an arhtmetic operation on this, to extract the first number. This works with awk as it will convert any string starting with numbers into a number by ignoring anything after it. So q=u+0
creates
q=16
Finally, we remove anything which is not a character from u
leading to
u="minutes"
The next step we redefine tmp
by removing whatever we already processed.
tmp=", 2 seconds"
and start the process all over.
Note that the uptime
command gets the data from /proc/uptime
So one approach is to get the first field value which is the total elapsed time in seconds and feed it to date
command:-
here is an example:-
$ cat /proc/uptime
8743161.15 7738916.50
$ date -d'-8743161.15 seconds'
Sat Jul 6 06:00:37 EDT 2019