我有这个文件:
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实用程序执行此操作?
答案 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
$
您可以从此处转到cat
和while
循环,read
所有行,并根据其结构处理每个行。 (请注意,在上面的方法中,您将松开引号字符,因为它们由shell解释。)处理这些部分可能会变得相当复杂,需要进一步的命令和条件。
因此,更好的选择包括使用awk
或Perl,以及从Java解决方案改编的字符串处理逻辑。在任何解决方案中,在每行中的某些位置拆分输入似乎是一个很好的第一步,因为grep
的单个,包罗万象的正则表达式似乎相当棘手。