【问题标题】:Shell script to validate csv fields用于验证 csv 字段的 Shell 脚本
【发布时间】:2014-08-16 15:20:30
【问题描述】:

我有一个包含 20 个字段的 csv 文件。我想要一个脚本来根据以下几点检查文件是否有效:

  • 它需要有 20 个用管道分隔的字段。
  • 20 个字段中的每一个都应匹配一个正则表达式。
  • 了解任何正则表达式不匹配的行号和字段号。

例如:

f1|f2|f3|...|f20
1|aaaa|Y|...|2014/06/25
2|bb|Y...|2014/06/25
3|ccc|N...|2014/06/25

regex:
f1 [0-9]
f2 [a-z]{2,4}
f3 [YN]
.
.
.
f20 [1-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]

最好的 shell 工具是什么?有没有类似的脚本?

【问题讨论】:

    标签: regex bash shell unix awk


    【解决方案1】:

    Unix 系统中最好的工具是 awk 来完成这项工作。您可以使用这样的 awk 命令:

    awk 'BEGIN{FS=OFS="|"} NF!=20{print "not enough fields"; exit}
    !($1~/^[0-9]$/) {print "1st field invalid"; exit}' file.csv
    

    【讨论】:

    • 这是一个很好的解决方案!谢谢,但我还需要知道某些字段是否与它不匹配以及行和字段编号。
    • 当然也可以使用 ask 来完成。您可以使用单独的字段检查和单独的处理程序,而不是使用&& 检查多个字段。开始编写您的询问命令,如果遇到问题,请告诉我。
    • 我不明白如何检查两个或更多字段。
    【解决方案2】:

    您可能需要考虑为此使用 perl 脚本:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    my @regexes = (
        qr/\d/,                  # regex quotes qr/ /
        qr/[a-z]{2,4}/, 
        qr/[YN]/,
        #etc. put the rest of the regexes here
    );
    
    while (<>) {                 # loop through every line of file
        my @fields = split /\|/; # split on pipe, needs escaping
        if (@fields != 20) {
            print "incorrect number of fields on line $.\n";
            exit;
        }
        for my $f (0..$#fields) { # loop through all fields
            unless ($fields[$f] =~ $regexes[$f]) { # regex match
                print "invalid field on line $., field ", ($f+1), "\n";
                exit;
            }
        }
    }
    

    如果将脚本保存为valid.pl 并使其可执行chmod +x valid.pl,则可以将其称为./valid.pl filename。目前脚本将在遇到第一个问题时立即退出。如果您删除 exit 语句,它将列出该文件的所有问题。

    如果您不熟悉 perl,$. 是一个特殊变量,其中包含 while 循环中的行号。 $#fields 是数组 @fields 的最后一个索引的值,所以 0..$#fields 等价于列表 0,1,...,19。数组索引从 0 开始,所以我在字段编号上加了 1。

    【讨论】:

    • +1:虽然$line 可以通过直接使用$. 来避免,但您需要在$f 上加一,因为索引从0 开始。
    • @jaypal 谢谢。我将$. 分配给一个变量,希望能让不熟悉perl 的人更清楚代码,尽管我同意它是多余的。也同意了字段号,会编辑的。
    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多