如何使用 grep 从结构化文本文件中查找信息

如何使用 grep 从结构化文本文件中查找信息

该文本文件包含最畅销的歌曲。它的结构如下:

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

我试图找到没有进入第一名(第五场)的歌曲,即Wonderwall.我不确定如何指定第五个字段。我的想法是使用cat top50.txt | grep-vE "^[^*,*,*,*,[1],]".但是,这不起作用,我不知道为什么。

我也想找销量200万的歌曲

但我认为在弄清楚如何针对grep某个特定领域之前我无法做到这一点。

答案1

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第五个字段:

$ 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

这意味着“准确找到 4 次重复的一个或多个非,( [^,]+),后跟逗号,然后是 a1和逗号”。

你的尝试是在寻找完全不同的东西。在正则表达式中,[ ]表示字符类。 So 的[abc]意思是“其中之一a,或者b,或者c”,并且[^abc]意味着“其中之一任何事物除了ab、 或c。 So与 a 、 a 、 a 、 a或 a 以外的任何字符[^*,*,*,*,[1],]相同,并且将匹配任何字符。我认为你正在尝试做这样的事情:[^*,[]1][]1,*

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

the*是修饰语,意思是“前面的 0 个或多个”。所以它本身没有任何意义。要匹配任何字符 0 次或多次,您可以单独使用.*not *。接下来,单个字符.*将一直匹配到行尾。这称为“贪婪匹配”。对于非贪婪,要找到可能的最短匹配而不是最长匹配,您想要?这就是我.*?上面使用的原因。

相关内容