仅当第一行与模式匹配时才使用 Awk 解析文件

仅当第一行与模式匹配时才使用 Awk 解析文件

我需要询问 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 ...

相关内容