我打算在虚拟文件上使用“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
的行如果解析器一旦遇到 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 中测试)
$ 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
假设您不希望像
-
和 ,
这样的非单词组成字符本身算作单词,并且如果多行具有相同数量的单词,您希望将它们全部打印出来,这可能是你想要的,使用任何 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