How can I subtract timestamp results from `date` in one line of shell? - bash

I can generate two timestamps like so:
date +"%s" -d "$(curl -s --head http://google.com | grep ^Date: | sed 's/Date: //g')"
// Result: 1417800327
date +"%s"
// Result: 1417800325
How can I subtract them with only one line?
echo "$((1417800327-1417800325))"
// Result: 2
But I want something closer to:
echo "$(( (date +"%s" -d "$(curl -s --head http://google.com | grep ^Date: | sed 's/Date: //g')") - (date +"%s")))"

Try doing this :
LANG=C echo $(( $(date +%s) - $(date -d "$(curl -s --head http://google.com 2>&1 | awk -F'Date: ' '/^Date:/{print $2}')" +%s) ))
or splitted multi-lines for readability :
LANG=C echo $((
$(date +%s) - $(
date -d "$(curl -s --head http://google.com |
awk -F'Date: ' '/^Date:/{print $2}'
)" +%s)
))

#!/bin/bash
##On Linux. start time, do something, find end time.
st=`date +%s`; sleep 10; et=`date +%s`;
##On SunOS instead of using date command, use `truss /usr/bin/date 2>&1 | grep ^time | awk -F"= " '{print $2}'`;
##substract to find elapsed time
elt=$((et-st));
##find elapsed hours, minutes, seconds
eh=$((elt/3600)); em=$(($((elt%3600))/60)); es=$(($((elt%3600))%60));
elt=`printf "%02d:%02d:%02d%s" $((eh)) $((em)) $((es))`;
##show elapsed time in user friendly way
echo - Elapsed time: $elt
Output:
- Elapsed time: 00:00:10

Using a subshell function with one big command bash line
(timestamp=`date +"%s" -d "$(curl -s --head http://google.com | grep ^Date: | sed 's/Date: //g')"`;date=`date +"%s"`;let "time_difference= $timestamp-$date";echo "$time_difference"; )

Related

Pipe CURL result to BC

I have a CURL command
echo "{cur_format}" | curl -w #- -s -o /dev/null https://example.com
Let's say the above command outputs a string of "I waited 1 day".
How can I convert "I waited 1 day" to "I waited 24 hours" (i.e. pipe "1 * 24" to the bc command")?
Thank you.
I managed to resolve this by using "awk" command. For example,
echo "{cur_format}" | curl -w #- -s -o /dev/null https://example.com | awk -F'[:\|]' '{print $1 ":" (($2*24)) "|" $3 "|" $4;}'
Note that -F'[:\|]' is a list of any delimiters you need.

How can I find time difference between two server timestamps?

This outputs the closest Google server's time:
// Closest Google Server:
date +"%s" -d "$(curl -s --head http://google.com | grep ^Date: | sed 's/Date: //g')"
// Result: 1234
This outputs my local server time:
// Server
date +"%s"
// Result: 1235
How can I fetch the seconds between each result? (in the example above: 1)
Strictly answering your question, how about:
echo $(( $(date +"%s") - $(date +"%s" -d "`curl -s --head http://google.com | grep ^Date: | sed 's/Date: //g'`") ))

connections duration calculation process time

I am using the following code in bash linux to extract time duration for each connection
for a in folder/*.pcap
do
difference=$(echo $(tshark -r $a -T fields -e frame.time_epoch | tail -n 1) - $(tshark -r $a -T fields -e frame.time_epoch | head -n 1) | bc)
echo $difference
done
However, the process time is very high (1 minute for 100 pcaps). Any ideas how to improve process time?
Would this work:
myfun() {
a=$1
difference=$(echo $(tshark -r $a -T fields -e frame.time_epoch | tail -n 1) - $(tshark -r $a -T fields -e frame.time_epoch | head -n 1) | bc)
echo $difference
}
export -f myfun
parallel myfun ::: folder/*.pcap
You can install GNU Parallel simply by:
wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
Watch the intro videos to learn more: http://pi.dk/1
10 seconds installation:
wget pi.dk/3 -qO - | sh -x

how to convert 2012-05-03T25:00:00 to 2012-05-04T01:00:00 in unix

I am not sure how this will be done in unix can anybody help/suggest to convert
2012-05-03T25:00:00 to 2012-05-04T01:00:00 in Unix command/script
In my file I have more than one occurrence with different times those needs to converted to next day
2012-05-03T25:00:00 to 2012-05-04T01:00:00
2012-05-03T26:50:00 to 2012-05-04T02:50:00
2012-05-03T31:59:59 to 2012-05-04T07:59:59
etc
I tried it but somehow sed is not working
Date.txt
2009-09-12T05:18:#00#+10:00,D,
2009-09-12T05:24:00+10:00,2009-09-12T05:24:#00#+10:00,D,
2009-09-12T05:25:00+10:00,2009-09-12T05:25:#00#+10:00,D,
2009-09-12T05:27:00+10:00,2009-09-12T05:27:#00#+10:00,D,
2009-09-12T30:29:00+10:00,2009-09-12T05:29:#00#+10:00,D,
2009-09-12T29:31:00+10:00,2009-09-12T05:31:#00#+10:00,D,
2009-09-12T28:33:00+10:00,,D,
2009-09-12T27:00:#00#+10:00,U,
2009-09-12T26:01:00+10:00,2009-09-12T05:01:#00#+10:00,U,
2009-09-12T24:04:00+10:00,2009-09-12T05:04:#00#+10:00,U,
2009-09-12T24:59:59+10:00,2009-09-12T05:06:#00#+10:00,U,
2009-09-12T30:08:00+10:00,2009-09-12T05:08:#00#+10:00,U,
2009-09-12T31:59:59+10:00,2009-09-12T05:10:#00#+10:00,U,
2009-09-12T05:17:00+10:00,,U,
2009-09-12T25:25:#00#+10:00,D,
script.sh
awk -F"T" -v OFS=',' '{print $1}' date.txt > tmpdate
uniq -d tmpdate > tmpuniq
rm tmpdate
date1=`cat tmpuniq`
date2=`date --set="$date1" +%F`
date3=$(date --date="$date2" -d "+1 day" +"%F")
T1=$date2+"T24"
T2=$date3+"T00"
echo $T1
echo $T2
dos2unix date.txt
#sed -i 's/$T1/$T2/g' date.txt > test.txt
#sed -i 's/"$T1"/"$T2"/g' date.txt > test.txt
sed -i 's/'$T1'/'$T2'/g' date.txt
Any help much appreciated
If you have Tcl on your system, the clock command makes it pretty easy:
set t 2012-05-03T31:59:59
lassign [split $t T] date time
lassign [split $time :] hour min sec
set base [clock scan $date -format %Y-%m-%d]
set new [clock add $base $hour hours $min minutes $sec seconds]
puts [clock format $new -format %Y-%m-%dT%T] ;# -> 2012-05-04T07:59:59
Update for cygwin:
first, using the cygwin installer, install the version 8.5.x of the "tcl" package (located in the Interpreters category). Then, you can do this
normalize_time() {
printf '
lassign [split "%s" T] date time
lassign [split $time :] hour min sec
set base [clock scan $date -format %%Y-%%m-%%d]
set new [clock add $base $hour hours $min minutes $sec seconds]
puts [clock format $new -format %%Y-%%m-%%dT%%T]
' "$1" | tclsh
}
normalize_time 2012-05-03T31:59:59
You will basically need to parse the erroneous time specification, convert everything to seconds, add it back together, and convert it back to a proper date.
date -d "date" +%s produces seconds since January 1, 1970. date -d #1234567890 converts a date in this format back to a regular human-readable date.
#!/bin/sh
IFS=T:
while read date hh mm ss; do
basedate=$(date -d "$date" +%s)
date -d #$(echo "$basedate+($hh*60*60)+($mm*60)+$ss" | bc) +%FT%T
done <<EOF
2012-05-03T25:00:00
2012-05-03T26:50:00
2012-05-03T31:59:59
EOF
I didn't have bc on this computer so I replaced my original attempt with a small awk script, but it's not very readable.
awk 'END { print '"$basedate"'+('"$hh"'*60*60)+('"$mm"'*60)+'"$ss"'}' </dev/null
If you don't have a recent enough version of GNU date, you can find some alternative ways at http://www.antonolsen.com/2006/04/06/bash-convert-unix-timestamp-to-a-date/
finally I got a solution with a bug (if date is last day of the month then this will not work but I can live with that)
and did a clumsy job
date1=`cat date.txt | awk -F. '{print substr($1,1,10)}'|uniq |head -1`
echo $date1
date2=$date1"T24"
date21=$date1"T25"
date22=$date1"T26"
date23=$date1"T27"
date24=$date1"T28"
date25=$date1"T29"
date26=$date1"T30"
date27=$date1"T31"
date3=$(date --date="$date1" -d "+1 day" +"%F")
echo $date2
cat date.txt | grep "$date2"
tmpdate=`echo $date1 | sed -e 's/-//g'`
echo $tmpdate
date4=`echo $(date -d $(echo \`expr $tmpdate + 1\`F) +"%F")`
echo $date4
date41=$date4"T00"
date42=$date4"T01"
date43=$date4"T02"
date44=$date4"T03"
date45=$date4"T04"
date46=$date4"T05"
date47=$date4"T06"
date48=$date4"T07"
sed -i 's/'$date2'/'$date41'/g' date.txt
sed -i 's/'$date21'/'$date42'/g' date.txt
sed -i 's/'$date22'/'$date43'/g' date.txt
sed -i 's/'$date23'/'$date44'/g' date.txt
sed -i 's/'$date24'/'$date45'/g' date.txt
sed -i 's/'$date25'/'$date46'/g' date.txt
sed -i 's/'$date26'/'$date47'/g' date.txt
sed -i 's/'$date27'/'$date48'/g' date.txt
If anyone wants to improve this script please go ahead.
Once again thanks to all.
First, use cat 'yourfile' to open it. Then do a loop on each line. Then use grep and cut. That's really simple to do and the most efficient way for you to learn is to go through the man pages of cat, grep, and cut.
Hope it'll help.

Shell script comparing dates

I'm working on a shell script that scrapes a date off a webpage and then checks if it is in the last three days of the current date (running it in Cygwin). If the test passes, it simply echoes "PASS", and if it fails, it echoes "FAIL";
However, when I run my script, I get the following:
integer expression expected: 1317618000
FAIL
Here is the script:
updateStr=$(curl "http://www.mywebsite.com" | grep "Last Update")
dateStr=(`echo $updateStr | sed -e 's/.*Last Update: \([^<]*\)<.*/\1/'`)
update=$(date -d "$dateStr" +%s)
epoch=$(date -d "-3 days ago" +%s)
test "$update" -ge "$epoch" && echo "PASS" || echo "FAIL"
Any ideas on what the issue is?
Edit
Here is the result of running bash -x on the script:
$ bash -x check_date.sh
++ curl http://www.mywebsite.com
++ grep 'Last Update'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6542 100 6542 0 0 789 0 0:00:08 0:00:08 --:--:-- 1544
+ updateStr=' <span style="float:right">Last Update: 10/3/2011 2:
'8:45 AM</span></p>
++ echo '<span' 'style="float:right">Last' Update: 10/3/2011 2:58:45 'AM</span><
'p>
++ sed -e 's/.*Last Update: \([^<]*\)<.*/\1/'
' dateStr='(10/3/2011 2:58:45 AM)
' +%ste -d '(10/3/2011 2:58:45 AM)
+ update=$'1317618000\r'
++ date -d '-3 days ago' +%s
+ epoch=$'1317938194\r'
+ test $'1317618000\r' -ge $'1317938194\r'
: integer expression expected1317618000
+ echo FAIL
FAIL
Update
I tried removing the carriage returns that appear in the date outputs, but it's still not working. Here is the updated script:
updateStr=$(curl "http://mywebsite.com" | grep "Last Update")
dateStr=$(echo $updateStr | sed -e 's/.*Last Update: \([^<]*\)<.*/\1/')
update=$(date -d "$dateStr" +%s | tr -d '\r')
epoch=$(date -d "3 days ago" +%s | tr -d '\r')
echo "Last Update: $update"
echo "Epoch Date: $epoch"
test "$update" -ge "$epoch" && echo "PASS" || echo "FAIL"
And here is the result:
$ bash -x ./check_date.sh
++ curl http://mywebsite.com
++ grep 'Last Update'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6542 100 6542 0 0 17398 0 --:--:-- --:--:-- --:--:-- 19704
+ updateStr=' <span style="float:right">Last Update: 10/6/2011 2:
'0:02 AM</span></p>
++ echo '<span' 'style="float:right">Last' Update: 10/6/2011 2:40:02 'AM</span><
'p>
++ sed -e 's/.*Last Update: \([^<]*\)<.*/\1/'
' dateStr='10/6/2011 2:40:02 AM
' +%ste -d '10/6/2011 2:40:02 AM
++ tr -d '\r'
+ update=$'1317886802\r'
++ date -d '-3 days ago' +%s
++ tr -d '\r'
+ epoch=$'1318184767\r'
' echo 'Last Update: 1317886802
Last Update: 1317886802
' echo 'Epoch Date: 1318184767
Epoch Date: 1318184767
+ test $'1317886802\r' -ge $'1318184767\r'
: integer expression expected: 1317886802
+ echo FAIL
FAIL
The carriage returns might be in your script itself. Try running dos2unix on your script.
Try this:
update=$(date -d "$dateStr" +%s | tr -d '\r')
epoch=$(date -d "-3 days ago" +%s | tr -d '\r')
That will get rid of the carriage returns at the end of each number, which might help.
bash is determining from context (the presence of '\r' in this case) that these are strings and not integers. The '-ge' binary operator expects integer arguments and so it's throwing an error. Tom Zych's suggestion will work, as well as using string comparison operators, like '<' or '>', which might give unexpected results if the string is badly formatted for some reason. I'm not sure if there is a way to force date to output as an integer or not...
References:
http://tldp.org/LDP/abs/html/untyped.html
http://tldp.org/LDP/abs/html/comparison-ops.html

Resources