如何收集完整的行和匹配的部分行?

如何收集完整的行和匹配的部分行?

是否可以同时输出某行的thefull line和 the ?matched parts

假设我有这个输入

low [ 0]: 0xffff0000 Interesting description A
hi  [ 0]: 0xffff00a0 Interesting description B
low [ 1]:     0x5000 Interesting description C
hi  [ 1]:     0x6000 Interesting description D
...
hi  [15]:   0x806000 ...

我想提取十六进制值作为一个有趣的部分,然后提取完整的行。我使用过 Paste 和 2 个 grep 命令,但感觉非常庞大,我想避免进程替换 ( <())。这就是我得到的:

paste -d'\n' <(grep    '0x[0-9a-zA-Z]*' "$file") \
             <(grep -o '0x[0-9a-zA-Z]*' "$file")

还有什么更切题的方法可以做到这一点?我正在考虑 awk,但不确定是否可以轻松获取匹配部分并打印它(???如下):

/0x[0-9a-zA-Z]*/ { print $0 ; print ??? }

输出示例:

low [ 0]: 0xffff0000 Interesting description A
0xffff0000 
hi  [ 0]: 0xffff00a0 Interesting description B
0xffff00a0 
low [ 1]:     0x5000 Interesting description C
0x5000 
hi  [ 1]:     0x6000 Interesting description D
0x6000 
...
hi  [15]:   0x806000 ...
0x806000 

答案1

我可能会使用以下方法来做到这一点sed

sed -e '/.*\(0x[[:xdigit:]]*\).*/!d' -e p -e 's//\1/' file

这首先会丢弃格式中不包含十六进制数字的所有行0xnnnn...。如果一行没有被丢弃,它会打印未修改的行,并在再次输出之前仅用十六进制数字替换它。

最后一步重新使用第一个编辑表达式中使用的正则表达式,这意味着我们可以用\1括号内的子表达式(十六进制数字)捕获的子字符串替换匹配的任何内容(整行)。

答案2

对于任何 awk:

awk 'match($0,/0x[0-9a-zA-Z]*/) {print $0; print substr($0,RSTART,RLENGTH)}' file

使用 GNU awk:

gawk 'match($0,/0x[0-9a-zA-Z]*/,arr) {print $0; print arr[0]}' file

您可能会考虑替换0x[0-9a-zA-Z]*0x[[:xdigit:]]+

答案3

使用任何 awk:

$ awk '{r=$0; sub(/[^:]+/,""); print r ORS $2}' file
low [ 0]: 0xffff0000 Interesting description A
0xffff0000
hi  [ 0]: 0xffff00a0 Interesting description B
0xffff00a0
low [ 1]:     0x5000 Interesting description C
0x5000
hi  [ 1]:     0x6000 Interesting description D
0x6000
hi  [15]:   0x806000 ...
0x806000

我认为...您的问题中的那一行实际上并不存在于您的输入中,因此我将其删除。

相关内容