1

测试文件

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

没有变量的实际模式搜索可以正常工作:

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

使用失败的变量进行模式搜索

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

讨厌的 hack 使用 shell echo 包装变量,使其工作

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

关于我做错了什么或者这是否是 awk 中可能的功能的任何想法?

这些建议奏效了,我的结果有所不同:

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 和 4 返回完整的结果 前两个在到达模式后立即停止

4

4 回答 4

5

您需要将变量锚定到行首:

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

所以 09:02 匹配 09:02:01 但不匹配 17:09:02。

就我个人而言,我不会使用这个范围的东西,而是在适当的时候设置/清除/测试一个标志,因为它更具可扩展性。例如,尝试其中的每一个,看看是否容易操作打印或不打印分隔线:

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

我从您接受@sudo_Os 的回答中看到,您可能希望获得所有 09:02 时间,而不是停留在第一个时间。如果这是真的,只需使用字符串而不是 RE 比较:

$ 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

或者这会给出相同的结果:

$ awk -F: -v start="09:01" -v end="09:02" '$1FS$2>=start && $1FS$2<=end' file
于 2013-02-08T14:59:56.800 回答
3

比赛不应该是:

$ 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

你不想要所有的09:02:XX线条吗?

于 2013-02-08T11:31:58.260 回答
2

要使用 start 和 end 作为模式,您可以使用运算符明确告诉 awk ~

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

或与match()

awk -v start="09:01" -v end="09:02" 'match($0,start),match($0,end)'
于 2013-02-08T11:28:16.033 回答
1
awk -v start="09:01" -v end="09:02" 'substr($0,1,5) >= start && substr($0,1,5) <= end' test.txt

当时间范围跨越小时的顶部时,这将起作用,并且只会查看小时和分钟。不使用 $1,以避免“命中”具有前导空白但其他匹配的内容。

坦率地说,我会使用 BEGIN 和一些参数来设置开始/结束。因为你可以在一条线上获得很多东西,但这并不意味着你必须这样做,无论如何对我来说。

这是我使用的数据:

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
于 2013-02-08T13:50:03.750 回答