使用 awk 打印文件中存在的最大字数的行(如果是多行,则打印行)

问题描述 投票:0回答:3

我打算在虚拟文件上使用“awk”,以获得其中包含最大字段/单词数的行 - 考虑到,我使用空格作为“FS(字段分隔符)”。

我的虚拟文件如下:

$ awk '{print}' awkexfile.txt 
This
is
an
example
file,
which
we
will
use
for
awk
actions


This is a seperate line in this file

This is a line, with comma - ,

This is a line, with

我正在尝试打印行 (作为额外福利,还可以获取该记录的相应行号 NR)。

awk '{if (length($0) > max) max = length($0)} END {if (NF == max) print NR $0}' awkexfile.txt

我期待这样的输出: 15 这是该文件中的单独一行

我没有得到上述命令的任何输出。 我不确定,如果解析器遇到 END 后,awk 解析器是否会返回到 NF == max

的行
macos shell awk
3个回答
2
投票

如果解析器一旦遇到 END,awk 解析器是否会返回到 NF == max 的线

如果你想先检查所有行,然后输出那些匹配特定条件的行,你可能会使用所谓的 2-pass 解决方案,令

awkexfile.txt
内容为

This
is
an
example
file,
which
we
will
use
for
awk
actions


This is a seperate line in this file

This is a line, with comma - ,

This is a line, with

然后

awk 'FNR==NR{if (NF > max) max = NF;next}{if (NF == max) print FNR,$0}' awkexfile.txt awkexfile.txt

提供输出

15 This is a seperate line in this file
17 This is a line, with comma - ,

输出有多行,因为它们都有 8 个字段,这是看到的最大值。观察到

awkexfile.txt
作为参数出现了两次。说明:
FNR
是文件中的行数,
NR
全局行数,因此
FNR==NR
表示处理第一个文件时。如果当前行中的字段数 (
NF
) 大于迄今为止看到的最大值,则将其保存为 max,然后转到
next
行,即不执行任何其他操作。由于
next
前面描述的第二个操作仅应用于第二遍,如果字段数等于找到的最大值,则使用
print
文件中的行数 (
FNR
) 和整行 (
$0
) 进行剪切输出字段分隔符(默认为空格)。

(在 GNU Awk 5.3.1 中测试)


2
投票
$ awk '{count=0; 
        for (i=1;i<=NF;i++) count += ($i ~ /[[:alnum:]]/); 
        if (count>max) {max=count; linenum=NR; line=$0}} 
   END {print linenum,line}' file

15 This is a seperate line in this file

这将打印具有最大字数的第一行(至少包含一个字母数字字符)。如果有多个,则两遍算法会更容易。

$ awk 'NR==FNR {for (i=1;i<=NF;i++) count[FNR] += ($i ~ /[[:alnum:]]/); 
                if (count[FNR]>max) max=count[FNR]}                    
       max==count[FNR] {print FNR,$0}' file{,}

15 This is a seperate line in this file

2
投票

假设您不希望像

-
,
这样的非单词组成字符本身算作单词,并且如果多行具有相同数量的单词,您希望将它们全部打印出来,这可能是你想要的,使用任何 awk:

$ awk '
    {
        orig = $0
        gsub(/[^[:space:][:alnum:]_]+/, "")
    }
    NF > max {
        max = NF
        lines = ""
    }
    NF == max {
        lines = lines NR OFS orig ORS
    }
    END {
        printf "%s", lines
    }
' file
15 This is a seperate line in this file
© www.soinside.com 2019 - 2024. All rights reserved.