【问题标题】:loop add a comma after nth comma using awk循环使用awk在第n个逗号后添加一个逗号
【发布时间】:2026-02-09 10:35:01
【问题描述】:

我觉得这应该是一个相当直截了当的问题,但我似乎无法让它发挥作用。

我有一个 csv 文件,我需要在每行的第 n 个逗号后添加逗号。 我相信我必须使用 gsub 让它循环。 像

{gsub(/$nth/,/",")}

但我对 awk 的理解不够好,无法让它工作。

我的脚本的最终目标是检查一个单词是否存在,以及它是否没有在第 n 个逗号后添加逗号。

我正在像这样使用 grep 来处理该部分:

TEST1=$(cat $file | grep 'Sentence Skills')
 if [ $? -eq 1 ]
  then
  awk command to add comma after nth comma
 fi

如果不存在,我需要在第 n 个逗号后添加一个逗号,以确保所有内容都正确排列

更新 用示例输入和输出来澄清(我很抱歉,我原本不打算包含 grep if then fi 部分)

这是 csv 的示例:

last,first,A00XXXXXX,1888-01-01,2015-05-13,Reading Comprehension 97,Sentence Skills 104,College Level Math 76,Elementary Algebra 115,
last,first,A00XXXXXX,1888-01-01,2015-05-13,Elementary Algebra 34,
last,first,A00XXXXXX,1888-01-01,2015-05-13,College Level Math 64,Elementary Algebra 114,
last,first,A00XXXXXX,1888-01-01,2015-05-13,Reading Comprehension 87,College Level Math 64,Elementary Algebra 114,

这就是我需要的样子:

last,first,A00XXXXXX,1888-01-01,2015-05-13,Reading Comprehension 97,Sentence Skills 104,College Level Math 76,Elementary Algebra 115,
last,first,A00XXXXXX,1888-01-01,2015-05-13,,,,Elementary Algebra 34,
last,first,A00XXXXXX,1888-01-01,2015-05-13,,,College Level Math 64,Elementary Algebra 114,
last,first,A00XXXXXX,1888-01-01,2015-05-13,Reading Comprehension 87,,College Level Math 64,Elementary Algebra 114,

如果阅读理解不存在,我需要在第 5 个逗号后添加一个逗号,如果 Sentence Skills 不存在,我需要在第 6 个逗号后添加一个逗号,如果大学水平数学不存在,我需要在第 7 个逗号后添加一个逗号' t 存在,如果初等代数不存在则一个逗号。

如果其中任何一个确实存在,它不会添加逗号并跳到下一个。

【问题讨论】:

  • 请向我们展示示例输入和输出。既需要修改,也不需要修改。
  • 是在第n列还是第n个逗号之后,因为您在问题中都提到了。
  • 我已经添加了需要进一步澄清的输入和输出。我真的只需要知道如何在一定数量的逗号后在 csv 文件中添加逗号。我想我可以弄清楚其余的

标签: bash awk


【解决方案1】:

在我看来,用 解决它可能是一项艰巨的任务。在这里,您可以使用 的方法。不同之处在于我可以使用散列,对其进行排序并在数组中间添加项目splice

perl -F',' -lanE '
    BEGIN {
        %h = ( 
            5 => q|Reading Comprehension|,
            6 => q|Sentence Skills|,
            7 => q|College Level Math|,
            8 => q|Elementary Algebra|,
        );  
    };  
    for (sort keys %h) {
        if ($F[$_] !~ m/^$h{$_}/) {
            splice @F, $_, 0, q||;
            ++$_;
        }   
    }
    printf qq|%s,\n|, join q|,|, @F;
' infile

-F 具有相同的含义,因此我遍历哈希并检查该字段编号是否包含该值。如果不匹配,则在其前面插入一个空元素,最后一个printf 用逗号连接所有字段。它产生:

last,first,A00XXXXXX,1888-01-01,2015-05-13,Reading Comprehension 97,Sentence Skills 104,College Level Math 76,Elementary Algebra 115,
last,first,A00XXXXXX,1888-01-01,2015-05-13,,,,Elementary Algebra 34,
last,first,A00XXXXXX,1888-01-01,2015-05-13,,,College Level Math 64,Elementary Algebra 114,
last,first,A00XXXXXX,1888-01-01,2015-05-13,Reading Comprehension 87,,College Level Math 64,Elementary Algebra 114,

【讨论】:

  • 看起来很棒,我根本不懂 perl。我该如何运行它,我是否需要在我的 Linux 机器上安装/设置任何东西,或者它是否已经内置?我在哪里输入我需要它处理的文件名,然后输出将去哪里?
  • @moore1emu:试一试。它是单行的,只是分成几行以使其更具可读性。您可以从 shell 运行它。请注意,单引号后的最后一行是输入文件名。