Question

Here is my case.

bash ~]# TIME="2012-05-25 06:42:57"
bash ~]# echo "2012-05-25 00:16:51,610" | awk -v var=$TIME '{if ($0 < var) print $0}'

Then, here is the error message

awk: 06:42:57
awk:   ^ syntax error

I just want to pass a date range to my awk command. How to archive this? Please help. Thanks.

Modify the case

START_TIME="2012-05-24 00:00:00"
END_TIME="2012-05-24 01:00:00"
echo "2012-05-24 00:10:10" | awk -v "START=$START_TIME" -v "END=$END_TIME" '{ if ( $0 > START && $0 < END) print $0 }'

It seems not working in IF conditions.

awk: { if ( $0 < START && $0 > END) print $0 }
awk:                           ^ syntax error

After serval trying, seems found the solution with another approach.

echo "2012-05-24 00:10:10" | awk '{ if ( $0 > "'"$START_TIME"'" && $0 < "'"$END_TIME"'" ) print $0 }'

Not sure how to do it with awk variable "-v". Anyone have idears?

Was it helpful?

Solution

Quote your variable when passing it to AWK:

echo "2012-05-25 00:16:51,610" | awk -v "var=$TIME" '{if ($0 < var) print $0}'

OTHER TIPS

At least on my system, it appears that "END" is a reserved word even for variables. Awk uses END as it uses BEGIN, but I hadn't seen attempts to use it as a variable before. Note:

[ghoti@pc ~]$ START_TIME="2012-05-24 00:00:00"
[ghoti@pc ~]$ END_TIME="2012-05-24 01:00:00"
[ghoti@pc ~]$ echo "2012-05-24 00:10:10" | awk -v "START=$START_TIME" -v "END=$END_TIME" '{ if ( $0 < START && $0 > END) print $0 }'
awk: syntax error at source line 1
 context is
        { if ( $0 < START && $0 > >>>  END <<< ) print $0 }
awk: illegal statement at source line 1
[ghoti@pc ~]$ echo "2012-05-24 00:10:10" | awk -v s_time="$START_TIME" -v e_time="$END_TIME" '{ if ( $0 < s_time && $0 > e_time) print $0 }'
[ghoti@pc ~]$ 

Obviously this still isn't working, but now it's not working because of a misunderstanding about how comparisons work, rather than because we're trying to use a reserved word as a variable.

Looking at your if statement, it seems that you're trying to evaluate TRUE only if the comparison string is both BEFORE the start date and AFTER the end date. Barring theories of time being circular, I think we can assume that this logic is flawed.

So here's what I came up with. Note that this uses gawk's mktime() function, so it won't work everywhere.

[ghoti@pc ~]$ START_TIME="2012-05-24 00:00:00"
[ghoti@pc ~]$ END_TIME="2012-05-24 01:00:00"
[ghoti@pc ~]$ printf '2012-05-23 22:10:10\n2012-05-24 00:10:10\n2012-05-24 01:10:10\n' | gawk -v s_time="$START_TIME" -v e_time="$END_TIME" 'BEGIN { s=mktime(gensub(/[^0-9]/," ","G",s_time)); e=mktime(gensub(/[^0-9]/," ","G",e_time)); } { now=mktime(gensub(/[^0-9]/," ","G")); if ( now > s && now < e) print $0 }'
2012-05-24 00:10:10
[ghoti@pc ~]$ 

Spaced out for easier reading, the gawk script looks like this:

BEGIN {
    s=mktime(gensub(/[^0-9]/," ","G",s_time));
    e=mktime(gensub(/[^0-9]/," ","G",e_time));
}
{
    now=mktime(gensub(/[^0-9]/," ","G"));
    if ( now > s && now < e) print $0;
}

Obviously, this relies completely on the fact that your date/time specification matches mktime()'s input format so closely. But it works with the sample data in your question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top