簡體   English   中英

AWK 列匹配模式

[英]AWK column matching pattern

我正在嘗試編寫一個命令來查找 csv 文件中與模式匹配的特定列所在的行。 我正在為該列的模式匹配而苦苦掙扎

任務:打印第 5 列(col5date)為 2022 年 6 月、7 月或 8 月的行

示例 csv 文件:

col1 列2 列3 列4 col5date col6
A B C D asdd 2022年 asdd 22/7/4 某物
A B C D asdd 2022年 asdd 10/9/22 某物
A B C D asdd 2022年 asdd 12/12/20 某物
A B C D asdd 2020 asdd 2019 年 9 月 1 日 某物
A B C D asdd 2020 asdd 9/1/22 某物
A B C D asdd 2021年 asdd 19/9/22 某物
A B C D asdd 2021年 asdd 2/16/22 某物
A B C D asdd 2021年 asdd 22/6/16 某物

命令后的預期輸出:第一行和最后一行,因為日期是六月和七月。

我的 awk 命令:

cat file | awk -F'|' '$5 ~ /(6|7|8)\/*\/22$/'

在模式"/(6|7|8)\/*\/22$/"我想說
m/d/Y - m 為 6、7 或 8
* - 一天
22$ - 年份和列結束

像這樣,假設文件是csv (逗號)而不是tsv (制表符)甚至| (管道)分隔文件:

awk -F, '$5 ~ /^(6|7|8)\/.*\/22$/' file

但是您的樣本輸入中沒有匹配的行

我會用類似的東西

awk -F, '$5 ~ "^[6-8]/[^/]+/22$"'

所以你不必轉義 '/` 也可以拒絕格式錯誤的日期

模式的這一部分\/*重復 0+ 次正斜杠而不是匹配日期。

您可以將天數部分的匹配范圍縮小為數字(仍然無法驗證有效日期),並且可以省略cat命令。

awk -F'|' '$5 ~ /^[678]\/([1-9]|[12][0-9]|3[01])\/22$/' file

如果您使用逗號作為分隔符,請使用awk -F,

輸出

abcd|asdd|2022|asdd|7/4/22|something
abcd|asdd|2021|asdd|6/16/22|something

假設數據格式正確,您可以消除格式匹配。

$ awk -F, '$5~/^[6-8].*22$/' file

使用您顯示的示例和嘗試,請嘗試遵循awk代碼。

awk '$5~/^6\/([1-9]|1[0-9]|2[0-9]|30)\/[0-9]{2}$|^[7-8]\/([1-9]|1[0-9]|2[0-9]|3[0-1])\/[0-9]{2}$/'  Input_file

(對我來說)不清楚輸入文件是如何定界的,因此出於演示目的,我假設以逗號定界:

$ cat file
col1,col2,col3,col4,col5date,col6
abcd,asdd,2022,asdd,7/4/22,something
abcd,asdd,2022,asdd,10/9/22,something
abcd,asdd,2022,asdd,12/12/20,something
abcd,asdd,2020,asdd,9/1/19,something
abcd,asdd,2020,asdd,9/1/22,something
abcd,asdd,2021,asdd,9/22/19,something
abcd,asdd,2021,asdd,2/16/22,something
abcd,asdd,2021,asdd,6/16/22,something

一個awk想法:

awk -F',' -v mon='6,7,8' -v year="22" '        # define input delimiter as comma; OP provides comma-delimited list of numerical months along with desired year

BEGIN  { split(mon,a,",")                      # split input variable "mon" on commas and place results into array a[]
         for (i in a)                          # loop through indices of array a[] and ...
             months[a[i]]                      # build new array where numerical months are the indices of the array months[]
       }
FNR==1 { print; next }                         # print header row then skip to next line of input
       { split($5,a,"/")                       # split 5th field on "/" delimiter and place results into array a[]
         if (a[1] in months && a[3] == year)   # if a[1] is an index in the months[] array and a[3] matches the desired year then ...
            print                              # print current line to stdout
       }
' file

這會產生:

$ . ./dates.awk
col1,col2,col3,col4,col5date,col6
abcd,asdd,2022,asdd,7/4/22,something
abcd,asdd,2021,asdd,6/16/22,something

如果每一行中沒有任何其他日期:

 gawk -b '1 < NF' FS='[,|][6-8][/][^/]+[/]22[,|]'

如果您非常確定輸入中沒有格式錯誤的日期,那么更簡單:

 mawk '/[,|][6-8][^|]+22[,|]/'

我通常更喜歡使用方括號進行正則表達式特殊字符轉義,因為它在許多regex中比\\\\\\whiskey\\\\\\tango\\\\\\foxtrot\\\\更清晰地描繪了邊界es,額外的好處是不必擔心在awk實際執行之前通過的每個額外層“吃掉”了多少反斜杠

例如,正斜杠"/" :: 用於命令行分配 --

  • mawk可以輸入\/ ,而

  • gawk/nawk需要一對 — \\/

  • "[/]"是全 awk 變體友好的,當它是雙引號字符串形式時

對於開放式 /.../ 形式的正則表達式,mawk /…/ mawk/gawk可以使用 /...[/].../ 而nawk堅持額外的反斜杠 /...[\/].../ ,這在某種程度上破壞了選擇[…] /…[/]…/ /…[\/]…/理由\/\/\\+\\/\\\]\\[\\*\\……

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM