返回具有grep匹配的制表符分隔的csv文件的整列

时间:2014-03-13 12:37:07

标签: regex linux csv command-line grep

假设我有一个标签分隔的csv文件,如下所示:

a b c  
d e f  
g h i  

使用命令行实用程序,有没有办法可以返回匹配所需grep模式的整列,或者在上面的示例中,我想返回第二列的grep of b?

3 个答案:

答案 0 :(得分:1)

如果只有匹配,你可以这样做:

$ awk -v patt="b" 'FNR==NR {for (i=1;i<=NF;i++) $i~patt && col=i; next} {print $col}' file file
b
e
h

解释

它在文件中循环两次。首先获取匹配文本的列号。其次要打印那个特定的专栏。

  • -v patt="b"提供模式
  • 第一次读取时
  • FNR==NR {for (i=1;i<=NF;i++) $i~patt && col=i; next},遍历字段并检查模式是否匹配。如果是,请将列号存储在col var。
  • {print $col}打印所有行的特定列。

答案 1 :(得分:1)

 awk -F'\t' -v pat="b" 'NR==FNR{for(i=1;i<=NF;i++)if($i~pat)c[i];next}
                        {s="";for(i=1;i<=NF;i++)
                         if(i in c)s=s sprintf("%s\t", $i);
                         sub(/\t$/,"",s);print s}' file file

这条线完成了这项工作。

  • 它会打印与pat匹配的所有列,并保持column格式。
  • pat是正则表达式,您可以将shell变量传递给awk行
  • 输出遵循原始列顺序

看一下示例:(我在第3列中添加b以显示多个匹配案例):

kent$  cat f
a       b       c
d       e       b
g       h       i

kent$  awk -F'\t' -v pat="b" 'NR==FNR{for(i=1;i<=NF;i++)if($i~pat)c[i];next}{s="";for(i=1;i<=NF;i++)if(i in c)s=s sprintf("%s\t", $i);sub(/\t$/,"",s);print s}' f f
b       c
e       b
h       i

答案 2 :(得分:0)

您确实需要提示您文件的大小,运行频率以及您拥有的列数。但

  1. grep很快(比awk更快)
  2. 除非您的文件很大,否则它们可能会被缓存(因此可以两次读取它们)
  3. 根据上述观察,我会

    1. grep模式的文件(如果需要,将结果传递给uniq)
    2. 从grep的输出中计算出需要哪些列
    3. 使用-vCOLS =“c1 c2 c3 ...”运行awk,并打印一个简单的脚本,用于打印由c1,c2指定的列...