【问题标题】:awk manipulates csv fileawk 操作 csv 文件
【发布时间】:2012-05-22 19:23:36
【问题描述】:

我想使用 awk 读取 csv 文件。 csv 文件包含 5 列,c1、c2、c3、c4、c5。我想判断c1、c2和c3一起是唯一的,就像数据库约束一样。

这里是示例 csv 文件:

c1,c2,c3,c4,c5
1886,5141,11-2011,62242.57,52.71
1886,5140,11-2011,63763.75,52.22
23157666,4747,11-2011,71.07,83.33
1886,5141,11-2011,4645.45,2135.45

此时row1和row4违反了唯一性约束,提示错误信息。

如何用awk实现?提前非常感谢。

【问题讨论】:

    标签: shell csv awk


    【解决方案1】:
    awk -F, 'line[$1,$2,$3] {printf "Error: lines %d and %d collide\n", line[$1,$2,$3], NR; next} {line[$1,$2,$3] = NR}'
    

    【讨论】:

    • +1 这是一个不错的技巧。我不知道这有效。回想起来似乎很明显。
    【解决方案2】:

    这列出了每个重复的所有行。它只为每个集合输出重复消息一次

    awk -F, '{count[$1,$2,$3]++; line[$1,$2,$3] = line[$1,$2,$3] ", " NR} END {for (i in count) {if (count[i] > 1) {v=i; gsub(SUBSEP, FS, v); print "Error: lines", substr(line[i], 3), "collide on value:", v}}}'
    

    分成多行:

    awk -F, '
        {
            count[$1,$2,$3]++; 
            line[$1,$2,$3] = line[$1,$2,$3] ", " NR
        }
        END {
            for (i in count) {
                if (count[i] > 1) {
                    v = i;
                    gsub(SUBSEP, FS, v);
                    print "Error: lines", substr(line[i], 3), "collide on value:", v
                }
            }
        }'
    

    这是凯文答案的变体。

    【讨论】:

    • 谢谢,丹尼斯。感谢您的宝贵时间。
    • 嗨丹尼斯。该脚本适用于我的家用机器。但它在工作中显示“awk:第 1 行附近的语法错误 awk:第 1 行附近的非法语句”。是否有任何 awk 版本差异?谢谢。
    • 不应该有任何语法差异。该脚本在gawk 下运行,带有或不带有--traditional(或--posix)选项,因此它应该可以在其他版本的AWK 中工作。您使用什么操作系统/发行版以及什么版本的 AWK?顺便说一句,我的答案中有一个错误,不应该与语法错误有关。这只是一个不正确的索引。我会更正我的答案。
    • 嗨,丹尼斯,我是 awk。它显示“SunOS 5.9 上次更改:2000 年 7 月 7 日”。任何想法?谢谢。
    • 操作系统是 Solaris9。我找不到找到 awk 版本的方法。 awk --version 不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2016-05-04
    相关资源
    最近更新 更多