如何从命令行搜索并打印匹配的相应值?

Roc*_*y86 4 command-line sed awk

我有以下字符串,例如

2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]
Run Code Online (Sandbox Code Playgroud)

我想查找MATCH并打印它的值 10,使用awk. 我能够使用传统方法来做到这一点grepcut但想找到使用sed或 的方法awk

MATCH 可以在线上的任何位置。

Sté*_*las 9

sed -n 's/.* MATCH: \([^ ]*\).*/\1/p'
Run Code Online (Sandbox Code Playgroud)

将打印" MATCH: "在每个匹配行最右边出现的非空格字符序列。

-n告诉sed默认情况下不打印模式空间。如果替换成功ps命令的标志告诉sed打印模式空间(因此是替换的结果)。

所以:

sed -n 's/pattern/replacement/p'
Run Code Online (Sandbox Code Playgroud)

是打印成功替换结果的常用习惯用法。

请注意,以上假设输入是有效文本。由于.*匹配任何字符序列,它不会匹配不构成有效字符的字节序列。在以另一种编码处理文本时,这通常发生在 UTF-8 语言环境中。如果您遇到这种情况,您可能希望在上面的那一行前加上LC_ALL=C. 这使得sed将每个字节视为一个字符,因此没有可能的无效字节序列。这将在这里起作用,因为我们匹配的字符都来自可移植字符集。

标准awk没有任何等效的东西,因为它的功能不支持捕获组(在 中\(...\)捕获\1sub()

在那里,您需要求助于该match()功能:

awk 'match($0, / MATCH: [^ ]*/) {
       print substr($0, RSTART+8, RLENGTH-8)}'
Run Code Online (Sandbox Code Playgroud)

或者使用以下技巧:

awk -F ' MATCH: ' 'NF>1 {sub(/ .*/, "", $2); print $2}'
Run Code Online (Sandbox Code Playgroud)

(请注意,那些会考虑最左边出现的" MATCH: ")。

GNUawk有一个gensub()功能类似于sed'ss命令的功能,但设计错误在于它没有告诉您是否进行了任何替换。在这里,你可以这样做:

 gawk '(replacement = gensub(/.* MATCH: ([^ ]*).*/, "\\1", 1)) != $0 {
   print replacement}'
Run Code Online (Sandbox Code Playgroud)