Unix 在模式后提取字符串
我想提取client_id和id后面的数字,并在每行中配对client_id和id 例如,对于以下日志行Unix 在模式后提取字符串,unix,sed,awk,pattern-matching,Unix,Sed,Awk,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
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
我知道我需要使用sed或awk。但我不知道具体怎么做
谢谢这可能适合您:
awk -F "[):,]" '{ for (i=2; i<=NF; i++) if ($i ~ /id/) print $2, $(i+1) }' file
下面是一个有效的
awk
脚本(我把它放在多行上,让它更详细一点,这样你就可以看到发生了什么):
说明:
03 204
03 491
03 29
04 209
04 301
05 20
:调用awk'BEGIN{FS=“[\(\):,]”
,使用awk
(
)
和:
作为分隔字段的分隔符,
:仅对包含/client\u id/{
client\u id的行执行以下操作:
/pattern/{…}表示仅在具有“pattern”的行上执行此操作。对于注释框来说,长而正确的答案应该解释得太长。Thor,感谢您的详细解释。还有一个问题,关于行/client\u id/{,如果我写/client\u id/和{在两个不同的行中,输出混合了输入文件和正确的结果。为什么?@jerry:这很奇怪,我在这里得到一个错误for(i=1;i我更喜欢awk,但如果您想知道如何使用sed实现这一点,这里有一种使用GNU sed的方法 解析
按如下方式运行:/client\u id/{ :a s/(客户id:([0-9]+)[^(+\(id:([0-9]+)([^\n]+)(.*)/\1\4\5\n\2\3/ 助教 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//; }'
和客户机id:([0-9]+)
对,并将它们放在模式空间的末尾。每次传递时,id:([0-9]+)
都会被删除 最后的替换将删除循环中的剩余部分。这可能适合您(GNU-sed):id:([0-9]+)
如果行没有预期的字符串,请删除它/.*(\(客户端id:([0-9]+)[^(]*\(id:([0-9]+)/!d
通过复制s//\2\3\n\1/
并向前移动第一个client\u id
来重新安排行,从而减少连续迭代的行数id
打印到引入的换行符P
删除到引入的换行符D
是您在正文中所需的全部内容。谢谢Ed。我认为需要一个循环,因为存在多个“相关用户”。我想,'{print$2,$6}'
只会打印第一个的id。不错,但我的呆瓜抱怨它决定忽略括号前的``。这些可以安全地删除。不允许再编辑我自己的评论…我想添加的内容:字符集字符($6
和[
),只有以下是需要转义的元字符:]
。一些建议:去掉空语句(尾随分号)将\^]-
更改为简单地print cid of s id
(OFS的存在就是为了这个),不要在前面放\和在字符集中,由于client_id始终位于同一位置,您可以简单地将其设置为$3,然后从4开始循环。请参阅@steve's solution.Sampson,感谢您的详细解释。还有一个问题,关于行/client_id/{,如果我写/client_id/和{在两个不同的行中,输出混合了输入文件和正确的结果。为什么?@jerry这只是print cid,id
语法的一部分。简短的回答是:如果在awk脚本的同一行中最外层的awk
前面没有任何内容,则括号内的指令将对每一行执行。例如{
表示“仅在脚本开始时执行此操作”BEGIN{…}
,后跟一个换行符。据我所知,大括号需要与前面的条件在同一行。sed:file parse.sed第2行:未知命令
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
sed -r '/.*(\(client_id:([0-9]+))[^(]*\(id:([0-9]+)/!d;s//\2 \3\n\1/;P;D' file