V H
V H

Reputation: 8587

awk between 2 pattern search using variables does not appear to work

Test file

cat text.txt 
09:00:00 TESTING
09:00:01 TESTING
09:00:02 TESTING
09:00:03 TESTING
09:00:04 TESTING
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING
09:02:01 TESTING
09:02:02 TESTING
09:02:03 TESTING
09:03:00 TESTING
09:03:01 TESTING
09:03:02 TESTING
09:03:03 TESTING

Actual pattern search without variables that works fine:

cat ./text.txt|awk -v start="09:01" -v end="09:02" '/09:01/,/09:02/' text.txt
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING

Pattern search with variables that fails

awk -v start="09:01" -v end="09:02" '/start/,/end/' text.txt

Nasty hack to wrap variables using shell echo that makes it work

echo "awk -v start="09:01" -v end="09:02" '/$start/,/$end/' text.txt"
awk -v start=09:01 -v end=09:02 '/09:01/,/09:02/' text.txt

start="09:01"; end="09:02"; echo "awk -v start="09:01" -v end="09:02 text.txt" '/$start/,/$end/'"|/bin/sh
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING

Any ideas on what I be doing wrong or if this is a possible feature in awk ?

The suggestions have worked and I have had some difference in results:

1.

awk -v start="09:01" -v end="09:02" '$0~start,$0~end' text.txt
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING

2.

awk -v start="09:01" -v end="09:02" 'match($0,start),match($0,end)' text.txt
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING

3.

awk -v start="09:01" -v end="09:02" '$0~start{print}$0~end{print}' text.txt
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING
09:02:01 TESTING
09:02:02 TESTING
09:02:03 TESTING

4.

awk -v start="09:01" -v end="09:02"  '$1~start||$1~end' text.txt
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING
09:02:01 TESTING
09:02:02 TESTING
09:02:03 TESTING

3 and 4 return the complete results the top two stop as soon as it hits the pattern

Upvotes: 1

Views: 1497

Answers (4)

Bill Woodger
Bill Woodger

Reputation: 13076

awk -v start="09:01" -v end="09:02" 'substr($0,1,5) >= start && substr($0,1,5) <= end' test.txt

This will work when the time range spans the top of the hour, and will only look at the hours and minutes. $1 is not used, to avoid a "hit" on something that has leading blanks but otherwise matches.

To be blunt, I'd use BEGIN, and some arguments to set the start/end. Because you can get lots of stuff on a line, doesn't mean you have to, for me anyway.

Here is the data I used:

09:00:00 TESTING
09:00:01 TESTING
09:00:02 TESTING
09:00:03 TESTING
09:00:04 TESTING
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING
09:02:01 TESTING
09:02:02 TESTING
09:02:03 TESTING
09:03:00 TESTING
09:03:01 TESTING
09:03:02 TESTING
09:03:03 TESTING
02:09:01 toasted
19:01:01 toasted
  09:01:01 toasted
20:00:00 toasted 09:01:01

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203324

You need to anchor your variables to the start of the line:

awk -v start="09:01" -v end="09:02" '$0~"^"start,$0~"^"end' text.txt

so that 09:02 matches 09:02:01 but not 17:09:02.

Personally I wouldn't use this range stuff but instead just set/clear/test a flag when appropriate as that's MUCH more extensible. e.g. try each of these to see how easy it is to manipulate printing or not of the delimiting lines:

awk -v start="09:01" -v end="09:02" '$0~"^"start{f=1} f; $0~"^"end{f=0}' text.txt
awk -v start="09:01" -v end="09:02" 'f; $0~"^"start{f=1} $0~"^"end{f=0}' text.txt
awk -v start="09:01" -v end="09:02" '$0~"^"start{f=1} $0~"^"end{f=0} f;' text.txt
awk -v start="09:01" -v end="09:02" '$0~"^"end{f=0} f; $0~"^"start{f=1}' text.txt

I see from you accepting @sudo_Os answer that you may want to get all of the 09:02 times rather than stop at the first one. If that's true, just use string instead of RE comparison:

$ awk -v start="09:01" -v end="09:02" '$1>=start":00" && $1<=end":59"' file
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING
09:02:01 TESTING
09:02:02 TESTING
09:02:03 TESTING

or this would give the same result:

$ awk -F: -v start="09:01" -v end="09:02" '$1FS$2>=start && $1FS$2<=end' file

Upvotes: 5

Chris Seymour
Chris Seymour

Reputation: 85785

Shouldn't the match be:

$ awk -F: -v hour=9 -v start=1 -v end=2 '$1==hour && $2>=start && $2<=end' file
09:01:00 TESTING
09:01:01 TESTING
09:01:02 TESTING
09:01:03 TESTING
09:02:00 TESTING
09:02:01 TESTING
09:02:02 TESTING
09:02:03 TESTING

Don't you want all the 09:02:XX lines?

Upvotes: 3

Thor
Thor

Reputation: 47099

To use start and end as patterns you can explicitly tell awk with the ~ operator:

awk -v start="09:01" -v end="09:02" '$0 ~ start,$0 ~ end'

Or with match():

awk -v start="09:01" -v end="09:02" 'match($0,start),match($0,end)'

Upvotes: 2

Related Questions