该文本文件包含最畅销的歌曲。它的结构如下:
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]
意味着“其中之一任何事物除了a
、b
、 或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 *
。接下来,单个字符.*
将一直匹配到行尾。这称为“贪婪匹配”。对于非贪婪,要找到可能的最短匹配而不是最长匹配,您想要?
这就是我.*?
上面使用的原因。