【发布时间】:2021-06-17 15:42:37
【问题描述】:
我是 awk 的新手,我想对目录中的所有文件应用一个简单的 awk 命令,并分别获取每个文件的结果。 这些文件是制表符分隔的,我只需要对第 11 列中的每个值求和,然后为每个文件分别打印结果。我尝试了以下代码,但它不起作用。
for i in *;
do
awk -F '\t' '{sum += $11} END {print sum} "$i"'
done
谢谢!
【问题讨论】:
标签: awk
我是 awk 的新手,我想对目录中的所有文件应用一个简单的 awk 命令,并分别获取每个文件的结果。 这些文件是制表符分隔的,我只需要对第 11 列中的每个值求和,然后为每个文件分别打印结果。我尝试了以下代码,但它不起作用。
for i in *;
do
awk -F '\t' '{sum += $11} END {print sum} "$i"'
done
谢谢!
【问题讨论】:
标签: awk
你可以使用这个gnu awk:
awk -F '\t' '{sum += $11} ENDFILE {print FILENAME ":", sum; sum=0}' *
ENDFILE 块将在我们打印文件名和总和的每个文件的处理结束时运行。
如果你没有gnu awk,那么使用这个:
awk -F '\t' 'FNR==1 {if (sum) print fn ":", sum; sum=0; fn=FILENAME}
{sum += $11} END {print fn ":", sum}' *
【讨论】:
您的 shell 引用中似乎有一个简单的错字;这应该工作:
for f in *; do awk -F '\t' '{sum += $11} END {print sum}' -- "$f"; done
(-- 仅用于防止其中一个以连字符开头的文件名;一个名为i 的变量通常按照旧的 Fortran 约定是整数,因此将一个变量用于字符串有点不合常理);或替代
ls | while read -r f; do awk -F '\t' '{sum += $11} END {print sum}' -- "$f"; done
如果您想避免达到命令行长度限制的风险(在当前系统上很大但有限),但如果您的文件名中有换行符,这会中断(为什么?!..)。
如果您想在一次 Awk 调用中完成所有操作,您可以使用 FNR(文件内的记录数)和 FILENAME 来跟踪文件:
awk -F '\t' 'FNR==1 {if (f) print sum; sum = 0; f = FILENAME} END {print sum} {sum += $11}' -- *
或者(可以调用 awk 一次或多次)
ls | xargs awk -F '\t' 'FNR==1 {if (f) print sum; sum = 0; f = FILENAME} END {print sum} {sum += $11}' --
具有与上述相同的警告。
您可以通过放弃 POSIX 并使用 GNUisms 来防止文件名中的换行符,它使用 NUL(文件名中被禁止)而不是换行符(不被禁止)分隔项目,但除非您的脚本要在真正敌对的环境中运行,否则它可能不值得。
【讨论】: