使用awk在文件中进行精确匹配

时间:2011-03-07 19:22:55

标签: bash awk

我只是想知道如何使用awk进行完全匹配。

例如

$ cal 09 09 2009
   September 2009
Su Mo Tu We Th Fr Sa
   1  2  3  4  5
6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30



$ cal 09 09 2009 | awk '{day="9"; col=index($0,day); print col }'
17
0
0
11
20
0
8
0

正如您所看到的,上面的命令输出包含字符串/数字“9”的所有行的索引号,是否有办法在上面的第4行cal输出中生成awk输出索引号。 ?可能是一个更优雅的解决方案?

我正在使用awk使用cal命令获取日期名称。这是整行代码:

     $ dayOfWeek=$(cal $day $month $year | awk '{day='$day'; split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", array); column=index($o,day); dow=int((column+2)/3); print array[dow]}')

上面代码的问题是,如果找到多个匹配,那么我会得到多个结果,而我希望它只输出一个结果。

谢谢!

4 个答案:

答案 0 :(得分:4)

将对index()的号召仅限于那些“天”被空格包围的行:

awk -v day=$day 'BEGIN{split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", array)} $0 ~ "\\<"day"\\>"{for(i=1;i<=NF;i++)if($i == day){print array[i]}}'

概念证明

$ cal 02 1956
    February 1956
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29


$ day=18; cal 02 1956 | awk -v day=$day 'BEGIN{split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", array)} $0 ~ "\\<"day"\\>"{for(i=1;i<=NF;i++)if($i == day){print array[i]}}'
Saturday

更新

如果您要查找的是从某个日期开始的某一天,那么您应该使用date命令,如下所示:

$ day=9;month=9;year=2009; 
$ dayOfWeek=$(date +%A -d "$day/$month/$year")
$ echo $dayOfWeek
Wednesday

答案 1 :(得分:2)

你写了

  

cal 09 09 2009

我不知道接受日期作为输入的cal版本, 仅

 cal ${mon} (optional) ${year} (optional)

但是,这不会影响您的主要问题。

你写了

  

有没有办法在上面的第4行cal输出中生成awk输出索引号。?

NR(Num Rec)是你的朋友 并且有很多方法可以使用它。

cal 09 09 2009 | awk 'NR==4{day="9"; col=index($0,day); print col }' 

OR

cal 09 09 2009 | awk '{day="9"; if (NR==4) {col=index($0,day); print col } }' 

ALSO

在awk中,如果你有整个程序应该使用的变量赋值,那么最好使用BEGIN部分,这样分配只执行一次。在你的例子中没什么大不了的,但为什么要养成坏习惯; - )?

因此

cal 09 2009 | awk 'BEGIN{day="9"}; NR==4 {col=index($0,day); print col }'

最后 目前还不完全清楚你要解决的问题是什么。你确定你总是想要抓住4号线吗?如果没有,那你怎么建议解决这个问题?

问题陈述为“1.我正在尝试做X. 2.这是我的输入.3。这是我的输出.4。这是生成输出的代码”更容易回应。

看起来你正在尝试进行日期计算。使用gnu date命令可以提供更强大的通用解决方案。我看过很多有用的讨论,标记为bash,shell,(date?)。

我希望这会有所帮助。

答案 2 :(得分:1)

在内置时间功能的语言中,这样做要容易得多。 Tcl非常适合,但许多其他语言也是如此:

$ echo 'puts [clock format [clock scan 9/9/2009] -format %a]' | tclsh
Wed

答案 3 :(得分:0)

如果您希望awk仅输出第4行,请将规则限制为第4行:

$ awk 'NR == 4 { ... }'