Awk仅匹配多行文本中第一行的匹配

时间:2014-07-24 20:48:33

标签: regex macos bash shell awk

我正在尝试匹配特定数字(06:00)和(9:00),如果它是多行文件中一行的第一个匹配项。我对awk知识有限的问题似乎是我要么只获得第一个匹配,要么也匹配第二个匹配。我也想计算得到的匹配数和结束数,但由于它没有正确匹配我没有那么远。

Schedule in <06:00>:12 out <06:00>:0
Schedule in <08:00>:10 out <06:00>:0
Schedule in <06:00>:9 out <05:00>:0
Schedule in <07:00>:13 out <08:00>:0
Schedule in <06:00>:12 out <09:00>:0
Schedule in <09:00>:12 out <06:00>:0
Schedule in <07:00>:11 out <06:00>:0

我试过了:

awk '/06/||/09/' schedule.txt

awk '$1 ~ /\<06/||/\<09/ {print $1}' schedule.txt

正确输出:

Schedule in <06:00>:12 out <06:00>:0
Schedule in <06:00>:9 out <05:00>:0
Schedule in <06:00>:12 out <09:00>:0
Schedule in <09:00>:12 out <06:00>:0
4 Total Matches

2 个答案:

答案 0 :(得分:2)

怎么样:

awk '$3 ~ /<06/||/<09/ {print $0}' schedule.txt
#     ^                        ^

关键点是默认 awk将每个字符串标记为由空格分隔的单词。第一个&#34;字&#34;在$1中,在$2中排名第二,依此类推。 $0就是整行。

给出一条输入线:

Schedule in <06:00>:12 out <06:00>:0
<------> <> <--------> <-> <------->
   $1    $2    $3       $4    $5
<---------------------------------->
                 $0

我只是将您的awk程序更改为测试$3,这似乎是正确的字段。在匹配的情况下,我打印整行($0)。

作为旁注,print $0可能会缩短为print。接受awk中的字符串的许多命令/函数默认为$0


再加上几个&#34; frills&#34;:

sh$ awk '$3 ~ /<06/||/<09/ {count++; print $0} END {printf("%d Total Matches\n", count) }' schedule.txt
Schedule in <06:00>:12 out <06:00>:0
Schedule in <06:00>:9 out <05:00>:0
Schedule in <06:00>:12 out <09:00>:0
Schedule in <09:00>:12 out <06:00>:0
4 Total Matches

最后,正如@Jidder所说:

  

&#34;这可以全部缩减为:&#34;

awk 'END {print x,"Total Matches"} $3~/0[69]:/&&++x'

答案 1 :(得分:0)

Awk是一种编程语言,假设您循环遍历文件。我们可以利用awk中可用的所有功能,包括许多内置函数的文本。

在Awk中,您通常有明确定义的字段,但您不必这样做。在您的示例中,我们可以将每一行视为一个字段,我们可以使用substr来提取我们想要的信息。时间恰好是该行上的14个字符位置(第一列中的第一个字符是第1列而不是第0列)。我们想要从位置14开始的五个字符:

awk 'substr ($0, 14, 5) ~ /06|9:00/' test.txt

我将这5个字符与正则表达式/06|9:00/进行比较。如果此布尔表达式为true,则打印出整行。

这与更全面阐述的Awk计划相同:

awk '{
    if ( substr ( $0, 14, 5 ) ~ /06|9:00/ ) {
        print $0
    }
}' test.txt