在模式之后提取字符串

jer*_*rry 7 unix awk sed pattern-matching

我想在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)
Run Code Online (Sandbox Code Playgroud)

我想输出

03 204
03 491
03 29
04 209
04 301
05 20
Run Code Online (Sandbox Code Playgroud)

我知道我需要使用sed或awk.但我不确切知道如何.

谢谢

Ste*_*eve 5

这可能对你有用:

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

结果:

03 204
03 491
03 29
04 209
04 301
05 20
Run Code Online (Sandbox Code Playgroud)


sam*_*hen 4

这是一个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
Run Code Online (Sandbox Code Playgroud)

输出:

03 204
03 491
03 29
04 209
04 301
05 20
Run Code Online (Sandbox Code Playgroud)

解释:

  • 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;}:否则如果我们当前所在的字段是id,则将这client_id : id对打印到stdout
  • input_file_name:提供输入文件的名称作为awk脚本的第一个参数。