Grep并仅返回匹配列

时间:2016-03-03 03:43:58

标签: bash awk sed grep multiple-columns

如果我想从具有不同数量的列的文件中搜索,请执行以下操作:

ppl:apple    age:5    F    add:blabla    love:dog
ppl:tom    M    add:blablaa    love:cat
ppl:jay    age:3    M    love:apple
ppl:jenny    acc:jen    age:8   F   add:blabla

...

文件是制表符分隔的,我想要的输出是:

age:5
age:3
age:8
...

使用grep age:将返回整行,而 使用cut -f2会返回一些不需要的列:

age:5
M
age:3
acc:jen

并且cut -f2|grep age:grep age|cut -f2:都不起作用

我的数据范围可能是11-23列, 有没有更简单的方法来使用grep sed或awk处理它, 非常感谢

5 个答案:

答案 0 :(得分:2)

您可以使用以下脚本:

cat file|grep age|awk '{for(i=1;i<22;i++){if($i ~ /^age:/)print $i}}'

答案 1 :(得分:2)

-o本身可以使用--only-matching / grep -o '\<age:[0-9]\+' 开关,无需其他工具即可完成此操作。你应该能够做到:

\<

解释正则表达式中较不常见的部分:

  • image:123是一个零宽度断言,你在一个单词的开头(也就是说,年龄前面是一个非单词字符,或者出现在行的开头,但它实际上并不是匹配那个非单词的字符);这会阻止你匹配,比如:age:。它在技术上不需要空格,因此它匹配\t等;如果这是一个问题,请与cut本身匹配,然后使用tr\+将其删除。
  • [0-9]表示“匹配前一个字符类的1个或多个匹配项”(即\+,因此它匹配一个或多个数字)。 *相当于重复两次课程,第二个副本后跟[0-9][0-9]*,例如\+,除了它更短,一些正则表达式引擎可以更好地优化{{1}}。

答案 2 :(得分:1)

ShadowRanger's simple grep-based answer可能是最好的选择。

适用于GNU sed和BSD / OSX sed的解决方案:

sed -nE 's/^.*[[:blank:]](age:[0-9]+).*$/\1/p' file

使用 GNU sed,您可以简化为:

sed -nr 's/^.*\t(age:[0-9]+).*$/\1/p' file

两个命令都匹配整个输入行,如果它包含感兴趣的age:字段,则将其替换为捕获的字段(\1),然后打印结果;其他行被忽略。

原始答案,在澄清要求之前:

假设在age: 存在的行上,它始终是 2nd 制表符分隔字段,awk是最佳解决方案:

awk '$2 ~ /^age:/ { print $2 }' file
  • $2 ~ /^age:/仅匹配第二个以空格分隔的字段以文字age:
  • 开头的行
  • { print $2 }只打印该字段。

答案 3 :(得分:1)

您也可以使用sed

    sed -nr 's/^.*(age:.).*$/\1/p'  input_pattern.txt

其中input_pattern.txt包含数据。

答案 4 :(得分:1)

将regexp的搜索限制为第11至23列:

awk '{ for(i = 11; i <= 23; i++) { if ($i ~ /^age:/) print $i } }' file