我需要询问 CSV 文件的标题,如果存在列,则继续处理数据行。上下文是指数据包含列(具体取决于发出它的时间和内容)。
希望有一个“纯粹的”Awk 解决方案来将业务逻辑保持在通用语言中,但如果这是不可能的,则对有选择地传递标头与 Awk 脚本匹配的文件的方法感兴趣。
使用最新版本的 Gawk 始终是一种选择。
编辑添加伪代码:
如果标题中的列(NR==1):则继续处理文件的其余部分,否则停止处理文件
答案1
列出文件:
尝试
awk 'FNR == 1 && $4 == "whatever" { print FILENAME ;}' file1 ... filen |
这将选择具有第四列中的所有内容的所有文件。
如果您有有趣的名字,只需添加引号即可。
awk 'FNR == 1 && $4 == "whatever" { printf "\"s\"\n", FILENAME ;}' file1 ... filen |
处理一个文件
awk 'NR == 1 && $4 != "whatever" { exit ;} other patterns { other action;}' file
处理许多文件
awk 'NR == 1 && $4 != "whatever" { nextfile ;} other patterns { other action;}' file1 ... filen
可以理解为
- IF(条件不满足)
NR == 1 && $4 != "whatever"
- 然后跳过这个文件
{ nextfile ;}
- 否则继续
other patterns { other action;}
答案2
假设一个简单的逗号分隔文件,其中每个逗号都是分隔符(某些 csv 文件可能引用了不应被视为字段分隔符的逗号),当标题中的列为“SOMESTRING”时,以下内容将打印除标题之外的每一行”:
awk -F, '
FNR==1 {
for (i=1; i<=NF; i++)
if ($i == "SOMESTRING")
next
nextfile
}
1
' file1 file2 file3 file4
如果合适,可以用子字符串测试或正则表达式匹配操作替换字符串比较。
nextfile 不是 POSIX AWK 的一部分,但它很普遍;它至少在 gawk、nawk(在 *BSD 系统上使用)、mawk 和 busybox 中可用。
答案3
awk 'FNR==1 && ! /whatever/ { nextfile } ; ...remainder of awk script here...' list_of_files_to_process
这应该跳到下一个要处理的文件,除非“whatever”位于第 1 行。
我不记得是否nextfile
是 GNU awk 扩展或者它是否也可在其他 awks 中使用。手册mawk
页没有提到它,但在original-awk
.如果这对您很重要,请在依赖该功能之前检查一下。
如果您使用 GNU awk,您可能需要将该测试放在一个BEGINFILE
块中,例如:
BEGINFILE { FNR==1 && ! /whatever/ { nextfile } } ;
... remainder of awk script here ...