我想我有一个非常相似的问题这个但我发现它由于不清楚而关闭,所以我将创建一个新问题。
我有一个日志文件,其中包含具有多个详细信息的单行条目。
例如:
Mon Jan 22 12:12:12 2012 foo=blah foo2=blah2 foo3=Some longer sentence that can contain spaces and numbers somethingelse=blarg foo5=abcdefg
Mon Jan 22 12:13:12 2012 foo=blah foo2=blah3 foo3=another long sentence that could be the same or different that the prior log entry somethingelse=blarg foo5=112345abcdefg
Mon Jan 22 12:14:12 2012 foo=blah foo2=blah2 foo3=Foo923847923874Some longer sentence that can contain spaces and numbers somethingelse=blarg foo5=abcdefg
Mon Jan 22 12:15:12 2012 foo=blah foo2=blah2 foo3=Fooo02394802398402384Some longer sentence that can contain spaces and numbers somethingelse=blarg foo5=abcdefg
我只想提取 foo3 的内容值。换句话说,我想看到之后foo3=
但之前的所有内容somethingelse=
我想我可以做类似的事情grep -oP 'foo3=[\s\S]*somethingelse='
,但正则表达式太贪婪,最终导致“中止(核心转储)错误。是否有更有效的方法来做到这一点?
补充笔记:
- 该日志文件很大,有 40,000 多行。
答案1
如果只有一个人foo3
排队
sed -n '/foo3=/{s/.*foo3=//;s/\S*=.*//;p}' file.txt
禁止打印-n
除由 推动的任何行(选项)p
。对于包含以下内容的行foo3=
:
foo3=
将之前包含的所有内容(.*foo3=
) 替换为空 (//
)。- 删除所有以 some(
*
) 非空格 (\S
) 符号开头的内容=
。 - 打印两次替换后的残数 (
p
)。
其他
sed -n 's/.*foo3=\([^=]*\)\s\+\S*=.*/\1/p' file.txt
将整行替换为括号 ( )\1
中的模式 ( ) \(...\)
,其中包含除一些 ( ) 空格 ( )=
前后的任何符号,然后是一些非空格,并打印仅进行此类替换的行的剩余部分。foo3=
*
\s
=
答案2
sed '/^foo3=/P;/\n/!s/[^ ]\{1,\}=/\n&/g;D' <infile >outfile
您可能必须使用文字换行符来代替n
上面的内容,但这只会打印 foo3 和 foo4 之间的内容。
为了更快地处理,请更明确地说明它:
sed '/\n/s/ [^ ]*=.*//p;/\n/!s/foo3=/\n\n&/;D' | grep .
或者使用额外的grep
顶部也可以更快:
sed 's/[^ ]\{1,\}=/\n&/g' | grep '^foo3='
答案3
尝试这个:
$ grep -Po "(?<=foo3\=).*(?=\s*foo4)" file.txt