3

我有一个 csv(逗号分隔文件)。我想知道如何仅使用 grep 搜索第 7 和第 8 字段相同的模式(不使用cut)。我尝试过这样的事情:

grep -E '[^,]*,{6,6}' input.csv | grep '\(.*\)\(,\)\(\1$\)' | less

不幸的是,这不会打印任何东西。我怎样才能得到我需要的输出?

4

2 回答 2

3

假设没有什么像带有逗号的字段那样尴尬(因为如果前 8 个字段中有这样的字段,那么没有完整的 CSV 识别工具就无法处理文件),并且有第 9 个字段(所以第 7 个字段)和第 8 个字段后跟逗号)然后:

grep '^\([^,]*,\)\{6\}\([^,]*,\)\2' file.csv

第一位表示 6 个零个或多个非逗号序列,每个序列后跟一个逗号。然后是第 7 个(可能是空的)字段,后面有逗号;接下来是同样的事情(the \2)。

$ cat file.csv
a,b,c,d,e,f,g,g,i
a,b,c,d,e,f,g,h,i
a,b,c,d,e,f,hhh,hhh,i
,b,c,d,e,f,hhh,hhh,i
,,c,d,e,f,hhh,hhh,i
,,,d,e,f,hhh,hhh,i
,,,,e,f,hhh,hhh,i
,,,,,f,hhh,hhh,i
,,,,,,hhh,hhh,i
,,,,,,hhh,hhh,
$ grep '^\([^,]*,\)\{6\}\([^,]*,\)\2' file.csv
a,b,c,d,e,f,g,g,i
a,b,c,d,e,f,hhh,hhh,i
,b,c,d,e,f,hhh,hhh,i
,,c,d,e,f,hhh,hhh,i
,,,d,e,f,hhh,hhh,i
,,,,e,f,hhh,hhh,i
,,,,,f,hhh,hhh,i
,,,,,,hhh,hhh,i
,,,,,,hhh,hhh,
$

请注意,该g,h,i行没有出现在输出中(也不应该出现);其余的应该而且确实会出现。

所有这些都是使用 POSIX基本正则表达式或 BRE 完成的。如果您使用egrepor grep -E,您可以使用扩展正则表达式或 ERE,您可以放弃除\2;之外的所有反斜杠。您还可以处理包含 8 个字段的某些行和包含 9 个或更多字段的其他行的文件,但这不是常规的 CSV 文件。BRE 版本也可以修改为使用恰好有 8 列的 CSV 文件:

grep '^\([^,]*,\)\{6\}\([^,]*\),\2$' file.csv

使用正则表达式的部分技巧是对实现给定结果的不同方法有灵活的思维方式;通常有不止一种方法可以做到这一点。

于 2012-10-22T04:23:55.430 回答
1

如果您对 awk 感兴趣,那会更简单:

awk -F, '$7==$8' your_file

或在 perl 中:

perl -F, -ane 'if($F[6]==$F[7]){print}' your_file
于 2012-10-22T07:35:07.833 回答