Grep 并仅返回匹配列

Grep and returning only column of match

如果我想从具有不同列数的文件中进行搜索,如下所示:

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: 将 return 整行,而 使用 cut -f2 将 return 一些不需要的列:

age:5
M
age:3
acc:jen

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

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

您可以使用以下脚本:

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

可能是最好的选择。

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

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

使用 GNU sed 你可以简化为:

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

两个命令都匹配整个输入行,如果它包含感兴趣的age:字段,则将其替换为捕获的字段(</code>),并打印结果;其他行将被忽略。</p> <hr> <p>原始答案,在澄清要求之前:</p> <p>假设在 <code>age: 存在 的行上,它始终是 2nd 制表符分隔字段,awk 是最好的解决方案:

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

你也可以使用 sed

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

其中 input_pattern.txt 包含您的数据。

将正则表达式搜索限制在第 11 至 23 列:

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

grep 本身可以通过使用 -o/--only-matching 开关来完成此操作,无需其他工具。你应该能够做到:

grep -o '\<age:[0-9]\+'

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

  • \< 是一个零宽度的断言,你在一个单词的开头(也就是说,age 前面有一个非单词字符或出现在行的开头,但它是实际上不匹配那个非单词字符);这会阻止你匹配,比如 image:123。它在技术上不需要空格,所以它会匹配 :age: 或类似的东西;如果这是一个问题,请匹配 \t 本身并使用 cuttr 稍后将其删除。
  • \+表示"match 1 or more occurrences of the preceding character class"(也就是[0-9],所以匹配一位或多位数字)。 \+ 相当于重复 class 两次,第二个副本后跟 *,例如[0-9][0-9]*,除了更短,一些正则表达式引擎可以更好地优化 \+