使用 awk 進行精確匹配

使用 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”的所有行的索引號,有沒有辦法使 awk 僅在上面的 cal 輸出的第 4 行中輸出索引號。可能是更優雅的解決方案?

我使用 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]}')

上面程式碼的問題是,如果找到多個匹配項,那麼我會得到多個結果,而我希望它只輸出一個結果。

謝謝!

答案1

您可以只提供一行的grep輸出:cal

$ cal 09 09 2009 | grep -E '(^9 | 9 | 9$)' | awk ...

grep 匹配以下之一:

  • 行首有一個 9 後面跟著一個空格
  • A 9 周圍有空格
  • 行尾有一個空格,後面跟著一個 9。

這對你來說怎麼樣?

答案2

我會用類似的東西來做這個

dayOfWeek="$(cal $month $year |
             awk -v day=$day \
                'BEGIN {split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", days)}
                 NR > 2 {for (i = 1; i <= NF; i++) {if ($i == day) {print days[i]}}}')"

這裡,BEGIN在開始時執行以設定數組days;另一種模式在第 2 行及以上行觸發(跳過標題),逐步遍歷各列直至找到day,然後使用列號查找工作日。 $inawk是字段引用運算符;正如$1第一個欄位一樣,$n是由 的值編號的欄位n。我還將 $day 從 shell 傳遞到腳本,並在行開頭進行賦值awkNR是記錄號(行號);NF是線上的字段數。 (您可以分別設定RSFS來分別變更分隔記錄和欄位的內容。)

(反斜線換行符和管道後面的換行符|只是為了清晰起見並使其不滾動很多。

這次經受住了考驗。

答案3

答案4

試試一下:

cal 09 2009 | awk -v "num=9" '
    BEGIN {
        OFS="\t";
        day=" ?[^0-9]" num "([^0-9]|$)"
    }
    NR==2 {dow = $0}
    $0 ~ day {
        col=match(" " $0, day);
        print $0, col, substr(dow,col,2)
    }'

全部在一行:

cal 09 2009 | awk -v "num=9" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, col, substr(dow,col,2) }'

演示:

$ for i in {1..30}; do cal 09 2009 | awk -v "num=$i" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, num, col, substr(dow,col,2) }'; done
       1  2  3  4  5    1       7       Tu
       1  2  3  4  5    2       10      We
       1  2  3  4  5    3       13      Th
       1  2  3  4  5    4       16      Fr
       1  2  3  4  5    5       19      Sa
 6  7  8  9 10 11 12    6       1       Su
 6  7  8  9 10 11 12    7       4       Mo
 6  7  8  9 10 11 12    8       7       Tu
 6  7  8  9 10 11 12    9       10      We
 6  7  8  9 10 11 12    10      13      Th
 6  7  8  9 10 11 12    11      16      Fr
 6  7  8  9 10 11 12    12      19      Sa
13 14 15 16 17 18 19    14      4       Mo
13 14 15 16 17 18 19    15      7       Tu
13 14 15 16 17 18 19    16      10      We
13 14 15 16 17 18 19    17      13      Th
13 14 15 16 17 18 19    18      16      Fr
13 14 15 16 17 18 19    19      19      Sa
20 21 22 23 24 25 26    21      4       Mo
20 21 22 23 24 25 26    22      7       Tu
20 21 22 23 24 25 26    23      10      We
20 21 22 23 24 25 26    24      13      Th
20 21 22 23 24 25 26    25      16      Fr
20 21 22 23 24 25 26    26      19      Sa
27 28 29 30             28      4       Mo
27 28 29 30             29      7       Tu
27 28 29 30             30      10      We

以下是 Mohamed 連結到的腳本的改進:

cal 09 2009 | awk -v "d=9" 'NR==2 {split($0, dow)} NR == 3 {print $0, d, dow[7 - ($NF + 35 - d) % 7]}'

不需要headtail一堆if聲明。

相關內容