[英]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.