Grep

如何使用 grep 從結構化文本文件中查找資訊

  • November 15, 2022

該文本文件包含最暢銷的歌曲。它的結構如下:

Single,Artist,Record label,Released,Chart,Traditional sales peak,

一些範例行:

Imagine,John Lennon,Apple,Oct-75,1,1714351
Uptown Funk,Mark Ronson featuring Bruno Mars,RCA,Dec-14,1,1647310
Wonderwall,Oasis,Creation,Oct-95,2,1502270

我試圖找到沒有排名第一(第 5 場)的歌曲,即Wonderwall。我不確定如何單獨指定第五個欄位。我的想法是使用cat top50.txt | grep-vE "^[^*,*,*,*,[1],]". 但是,這沒有用,我不確定為什麼。

我也想找銷量200萬的歌曲

但我認為在我弄清楚如何將目標定位grep到某個領域之前我不能這樣做。

Grep 是錯誤的工具。您應該使用專為處理欄位而設計的工具,例如awk. 例如,要獲取第 5 個欄位大於 1 的所有行:

$ awk -F, '$5 > 1' file
Wonderwall,Oasis,Creation,Oct-95,2,1502270

或者其第 6 個欄位至少為 200 萬:

awk -F, '$6 >= 2000000' file

做這樣的事情是不可能的,grep因為那不會讓你比較價值。您能做的最好的事情就是像這樣進行一些可怕的黑客攻擊,以將這些行1作為第 5 個欄位:

$ grep -E '([^,]+,){4}1,' file
Imagine,John Lennon,Apple,Oct-75,1,1714351
Uptown Funk,Mark Ronson featuring Bruno Mars,RCA,Dec-14,1,1647310

並反轉匹配以獲得不是 1 的那些:

$ grep -vE '([^,]+,){4}1,' file
Wonderwall,Oasis,Creation,Oct-95,2,1502270

這意味著“找到一個或多個非,( [^,]+) 後跟一個逗號,然後是 a1和一個逗號的 4 次重複”。

您的嘗試是尋找完全不同的東西。在正則表達式中,[ ]表示一個字元類。So[abc]的意思是“ a, or b, or中的一個c”,[^abc]意思是“除, , or之外的任何一個。So 與So相同並且將匹配任何不是 a , a , a , a或 a的字元。我認為你正在嘗試做這樣的事情:a``b``c``[^*,*,*,*,[1],]``[^*,[]1]``[``]``1``,``*

$ grep -vE '^.*?,.*?,.*?,.*?,1,' file 
Wonderwall,Oasis,Creation,Oct-95,2,1502270

the*是一個修飾符,意思是“前面的 0 個或多個”。所以它本身沒有任何意義。要匹配任何字元 0 次或多次,您可以.*單獨*使用。接下來,一個 single.*將一直匹配到行尾。這稱為“貪心匹配”。對於非貪婪,找到可能的最短匹配而不是最長匹配,?這就是我在.*?上面使用的原因。

引用自:https://unix.stackexchange.com/questions/725024