在冒号后为冒号前的字段匹配模式的行提取字段

时间:2018-01-28 20:51:49

标签: linux bash shell

我有一个文件file1,如下所示:

tool1v1:1.4.4
tool1v2:1.5.3
tool2v1:1.5.2.c8.5.2.r1981122221118
tool2v2:32.5.0.abc.r20123433554

我想提取tool2v1tool2v2的值 我的输出应为1.5.2.c8.5.2.r198112222111832.5.0.abc.r20123433554

我写了以下awk但是没有给出正确的结果:

awk -F: '/^tool2v1/ {print $2}' file1
awk -F: '/^tool2v2/ {print $2}' file1

4 个答案:

答案 0 :(得分:2)

您可以使用grep:

进行过滤
grep '\(tool2v1\|tool2v2\)'

然后在使用sed:

之前删除部分
sed 's/^.*://'

此sed操作意味着:

^ - match from beginning of string
.* - all characters
up to and including the :

...并将此匹配的内容替换为空。

格式为sed 's/<MATCH>/<REPLACE>/'

整个命令:

grep '\(tool2v1\|tool2v2\)' file1|sed 's/^.*://'

结果:

1.5.2.c8.5.2.r1981122221118
32.5.0.abc.r20123433554

答案 1 :(得分:2)

grep -E也可以完成这项工作:

grep -E "tool2v[12]" file1 |sed 's/^.*://'

答案 2 :(得分:2)

如果你有一个支持Perl兼容的正则表达式(如GNU grep)的grep,你可以使用一个可变大小的look-behind:

$ grep -Po '^tool2v[12]:\K.*' infile
1.5.2.c8.5.2.r1981122221118
32.5.0.abc.r20123433554

-o选项只保留匹配而不是整个匹配行; \K与&#34相同;该行必须与左侧的内容匹配,但不要在匹配中包含它们。#/ p>

你也可以使用正常的后卫:

$ grep -Po '(?<=^tool2v[12]:).*' infile
1.5.2.c8.5.2.r1981122221118
32.5.0.abc.r20123433554

最后,修复几乎正确的awk(并在评论中指出):

$ awk -F: '/^tool2v[12]/ { print $2 }' infile
1.5.2.c8.5.2.r1981122221118
32.5.0.abc.r20123433554

答案 3 :(得分:0)

问题已经得到解答,但你也可以使用纯粹的bash来达到预期的效果

#!/usr/bin/env bash
while read line;do
  if [[ "$line" =~ ^tool2v* ]];then
      echo "${line#*:}"
  fi
done < ./file1.txt

while循环读取file.txt的每一行,=~执行正则表达式匹配以检查$line变量的值是否以toolv2开头},然后它向后修剪: