在模式之后提取一个string

我想提取client_id和id后面的数字,并在每一行中配对client_id和id。

例如,对于以下几行日志,

User(client_id:03)) results:[RelatedUser(id:204, weight:10),_RelatedUser(id:491,_weight:10),_RelatedUser(id:29, weight: 20) User(client_id:04)) results:[RelatedUser(id:209, weight:10),_RelatedUser(id:301,_weight:10) User(client_id:05)) results:[RelatedUser(id:20, weight: 10) 

我想输出

 03 204 03 491 03 29 04 209 04 301 05 20 

我知道我需要使用sedawk。 但我不知道如何。

谢谢

这是一个awk脚本,它可以工作(我把它放在多行上,使它更加冗长,所以你可以看到发生了什么):

 #!/bin/bash awk 'BEGIN{FS="[\(\):,]"} /client_id/ { cid="no_client_id" for (i=1; i<NF; i++) { if ($i == "client_id") { cid = $(i+1) } else if ($i == "id") { id = $(i+1); print cid OFS id; } } }' input_file_name 

输出:

 03 204 03 491 03 29 04 209 04 301 05 20 

说明:

  • awk 'BEGIN{FS="[\(\):,]"} :调用awk ,使用( ) :,作为分隔符来分隔你的字段
  • /client_id/ { :只对包含client_id的行执行以下操作:
  • for (i=1; i<NF; i++) { :遍历每行一个字段的字段
  • if ($i == "client_id") { cid = $(i+1) } :如果我们当前所在的字段是client_id ,那么它的值就是下一个字段。
  • else if ($i == "id") { id = $(i+1); print cid OFS id;} else if ($i == "id") { id = $(i+1); print cid OFS id;}否则,如果我们当前所在的字段是id ,那么将client_id : idstdoutstdout
  • input_file_name :提供输入文件的名称作为awk脚本的第一个参数。

这可能对你有用:

 awk -F "[):,]" '{ for (i=2; i<=NF; i++) if ($i ~ /id/) print $2, $(i+1) }' file 

结果:

 03 204 03 491 03 29 04 209 04 301 05 20 

这可能适用于你(GNU sed):

 sed -r '/.*(\(client_id:([0-9]+))[^(]*\(id:([0-9]+)/!d;s//\2 \3\n\1/;P;D' file 
  • /.*(\(client_id:([0-9]+))[^(]*\(id:([0-9]+)/!d如果行没有预期的字符串删除它。
  • s//\2 \3\n\1/通过复制client_id重新排列行,并提前移动第一个id ,从而减少连续迭代的行数。
  • P打印到引入的换行符。
  • D删除引入的换行符。

我更喜欢awk,但是如果你想知道如何用sed来做这个,那么这里有一个和GNU sed一起工作的方法。

parse.sed

 /client_id/ { :a s/(client_id:([0-9]+))[^(]+\(id:([0-9]+)([^\n]+)(.*)/\1 \4\5\n\2 \3/ ta s/^[^\n]+\n// } 

像这样运行它:

 sed -rf parse.sed infile 

或者作为一个单线:

 <infile sed '/client_id/ { :a; s/(client_id:([0-9]+))[^(]+\(id:([0-9]+)([^\n]+)(.*)/\1 \4\5\n\2 \3/; ta; s/^[^\n]+\n//; }' 

输出:

 03 204 03 491 03 29 04 209 04 301 05 20 

说明:

这个想法是重复匹配client_id:([0-9]+)id:([0-9]+)对,并把它们放在模式空间的末尾。 在每次通过时, id:([0-9]+)被删除。

最后的替换将循环中的剩余部分删除。