如何从行中剪切最后 3 个字段并打印总标记数

如何从行中剪切最后 3 个字段并打印总标记数

如何从以下 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

这将获取最后一个字段$NFsplit将其存储在,,并将结果“子字段”存储到数组中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

相关内容