在grep之后找到一个字符串

时间:2015-07-02 15:55:31

标签: bash awk grep cut

我有这个文件:

a=1 b=2 1234j12342134h d="a v" id="y_123456" something else 
a=1 b=2 1234j123421341 d="a" something else 
a=1 b=2 1234j123421342 d="a D v id=" id="y_123458" something else 
a=1 b=2 1234j123421344 d="a  v" something else 
a=1 b=2 1234j123421346 d="a.a." id="y_123410" something else 

我只想检索包含' id ='的行,而只检索id和第3列的值。最终产品应该是

1234j12342134h id="y_123456" 
1234j123421342 id="y_123458"
1234j123421346 id="y_123410"

1234j12342134h "y_123456" 
1234j123421342 "y_123458"
1234j123421346 "y_123410"

甚至

1234j12342134h y_123456 
1234j123421342 y_123458
1234j123421346 y_123410

我为表达式的开头和结尾尝试了grep -o,但是错过了第一个id块。我试过awk,但是对于带空格的列来说失败了。

我使用Java,但随着日志文件变大,速度很慢。

如何使用bash实用程序执行此操作?

2 个答案:

答案 0 :(得分:5)

使用GNU awk(第3个arg用于match()):

$ gawk 'match($0,/id="[^" ]+"/,a){ print $3, a[0] }' file
1234j12342134h id="y_123456"
1234j123421342 id="y_123458"
1234j123421346 id="y_123410"

与其他问题:

$ awk 'match($0,/id="[^" ]+"/){ print $3, substr($0,RSTART,RLENGTH) }' file
1234j12342134h id="y_123456"
1234j123421342 id="y_123458"
1234j123421346 id="y_123410"

或者如果你想剥离一些前导/尾随字符,可以采用以下几种方法:

$ gawk 'match($0,/id="([^" ]+)"/,a){ print $3, a[1] }' file
1234j12342134h y_123456
1234j123421342 y_123458
1234j123421346 y_123410

或:

$ awk 'match($0,/id="[^" ]+"/){ print $3, substr($0,RSTART+4,RLENGTH-5) }' file
1234j12342134h y_123456
1234j123421342 y_123458
1234j123421346 y_123410

答案 1 :(得分:-1)

仅使用Unix shell,可能 bash实用程序误认为只是内置(我自己),其read命令可以将每一行拆分为字段变量您选择的,基于输入字段分隔符IFS(默认为空)。例如,仅处理测试用例中的第一行

$ echo a=1 b=2 1234j12342134h d="a v" id="y_123456" something else | \
  if read ign1 ign2 f3 ign4 ign5 f6 rest
    then echo $f3 $f6;
  fi
1234j12342134h id=y_123456
$

您可以从此处转到catwhile循环,read所有行,并根据其结构处理每个行。 (请注意,在上面的方法中,您将松开引号字符,因为它们由shell解释。)处理这些部分可能会变得相当复杂,需要进一步的命令和条件。

因此,更好的选择包括使用awk或Perl,以及从Java解决方案改编的字符串处理逻辑。在任何解决方案中,在每行中的某些位置拆分输入似乎是一个很好的第一步,因为grep的单个,包罗万象的正则表达式似乎相当棘手。