loris
loris

Reputation: 469

awk: Preventing result being interpreted as shell command

I have some pairs of dates like the following

2012-11-23T09:26:20 2012-11-23T09:26:48 
2012-11-23T09:26:48 2012-11-23T09:26:48 
2012-11-23T09:26:26 2012-11-23T10:49:38 
2012-11-23T10:49:38 2012-11-23T10:49:38 
2012-11-23T09:26:30 2012-11-23T12:17:13 
2012-11-23T12:17:13 2012-11-23T12:17:13 
2012-11-23T09:26:33 2012-11-23T13:39:52 
2012-11-23T13:39:52 2012-11-23T13:39:52

I want to find the difference between the two date for each line. So far I have

awk '{cmd="$(( ( $(date -ud \""$2"\" +\"%s\") - $(date -ud \""$1"\" +\"%s\") ) ))"; cmd | getline diff; print diff }' < submit_start.txt

which produces

sh: 28: command not found

sh: 0: command not found

sh: 4992: command not found

sh: 0: command not found

sh: 10243: command not found

sh: 0: command not found

sh: 15199: command not found

sh: 0: command not found

I seem to get the result interpreted as a shell command and printing 'diff' just seems to add a newline. What am I doing wrong?

Upvotes: 2

Views: 157

Answers (2)

Ed Morton
Ed Morton

Reputation: 203899

Use GNU awk for time functions:

$ gawk '{print secs($2) - secs($1)} function secs(t){gsub(/[^0-9]/," ",t); return mktime(t)}' file   
28
0
4992
0
10243
0
15199
0

Upvotes: 1

Tom Fenech
Tom Fenech

Reputation: 74685

You're missing an echo in your command:

awk '{cmd="echo $(( ( $(date -ud \""$2"\" +\"%s\") - $(date -ud \""$1"\" +\"%s\") ) ))"; cmd | getline diff; print diff }' file

Without the echo, you are attempting to execute each of the results as a command. I also removed the < from the line as it isn't necessary.

As Ed has mentioned in the comments, there are a few things to watch out for when using getline. You should test that it has succeeded and also close cmd when you're done:

awk '{cmd="echo $(( ( $(date -ud \""$2"\" +\"%s\") - $(date -ud \""$1"\" +\"%s\") ) ))"; diff = ( (cmd | getline line) > 0 ? line : -1 ); close(cmd); print diff }' file

Alternatively, there's no harm in using the shell for this task, as almost all of the work is being done outside of awk:

while read -r dt1 dt2; do
    echo "$(( $(date -ud "$dt2" +%s) - $(date -ud "$dt1" +%s) ))"
done < file

Upvotes: 4

Related Questions