如何从以下 cli 中剪切最后三个字段
cat file.txt
输出
Topic: __consumer_offsets Partition: 0 Leader: 1002 Replicas: 1002,1001,1003 Isr: 1002,1003,1001
Topic: __consumer_offsets Partition: 1 Leader: 1003 Replicas: 1003,1002,1001 Isr: 1002,1003,1001
Topic: __consumer_offsets Partition: 2 Leader: 1001 Replicas: 1001,1003,1002 Isr: 1002,1003,1001
Topic: __consumer_offsets Partition: 3 Leader: 1002 Replicas: 1002,1003,1001 Isr: 1002,1003,1001
预期产出
1002 1003 1001
1002 1003 1001
1002 1003 1001
1002 1003 1001
Number of tokens are : 12
我们尝试以下但没有成功
cat file.txt |awk '{print $NF-3,$NF-2,$NF-1}'
答案1
您可以使用逗号和空格字符作为字段分隔符:
awk -F "[, ]" '{print $(NF-2),$(NF-1),$NF}' file
还要编写最终的令牌语句:
awk -F "[, ]" '{print $(NF-2),$(NF-1),$NF;i++}END{print "Number of tokens are: " i*3}' file
答案2
由于您有两种不同的分隔符(空格和逗号分隔 - 我将忽略:
),因此您必须非常小心地选择字段分隔符。
默认值是(一个或多个)空格,因此您的语句$(NF-3),$(NF-2),$(NF-1)
等实际上应该打印
Replicas: 1002,1001,1003 Isr:
这是行中倒数第四个到倒数第二个空格分隔的标记。
对于您的任务,您将选择最后一个以空格分隔的标记,并在逗号处将其分开,如
awk '{n=split($NF,tokens,","); for (i=1;i<=n;i++) printf("%s%s",tokens[i],i==n?ORS:OFS)}' file.txt
这将获取最后一个字段$NF
,split
将其存储在,
,并将结果“子字段”存储到数组中tokens
。它返回此类子字段的数量并将其存储为n
.然后,我们打印所有这些子字段,分隔符字符可以是“输出字段分隔符”(OFS
,默认为空格)不是在数组末尾,或者当我们到达最后一个标记时的tokens
“输出记录分隔符”(默认为换行符)。ORS
这样,您还可以灵活应对最后一个字段中令牌数量的变化。
为了打印总计,该行将修改为:
awk 'NF{n=split($NF,tokens,","); for (i=1;i<=n;i++) printf("%s%s",tokens[i],i==n?ORS:OFS); tot+=n}\
END{printf("Number of tokens: %d\n",tot)}' file.txt
第一条规则之前的条件NF
确保忽略空行(它们会混淆计数逻辑)。
为了仅有的打印总计,您可以省略以下printf
语句:
awk 'NF{tot+=split($NF,tokens,",")} END{printf("Number of tokens: %d\n",tot)}' file.txt