Bash 添加尾随逗号以确保.csv行具有相同的列数

Bash 添加尾随逗号以确保.csv行具有相同的列数,bash,macos,csv,unix,awk,Bash,Macos,Csv,Unix,Awk,我有一个逗号分隔的文件,其中的行的列数不均匀 我想添加尾随逗号(带空值),以便每列具有最大列数 我目前有: i1, 12, 15 i2, 00, 01 i3 i4, 18, 21, 36 这只是一个示例,实际文件的最大列数有所不同 我对上述示例的期望输出是: i1, 12, 15, i2, 00, 01, i3, , , i4, 18, 21, 36 提前谢谢你 您可以使用awk来完成这项工作: $ awk 'BEGIN{FS=OFS=", "}NF<=3{for(

我有一个逗号分隔的文件,其中的行的列数不均匀

我想添加尾随逗号(带空值),以便每列具有最大列数

我目前有:

i1, 12, 15
i2, 00, 01
i3
i4, 18, 21, 36
这只是一个示例,实际文件的最大列数有所不同

我对上述示例的期望输出是:

i1, 12, 15,  
i2, 00, 01,  
i3,   ,   ,  
i4, 18, 21, 36

提前谢谢你

您可以使用awk来完成这项工作:

$ awk 'BEGIN{FS=OFS=", "}NF<=3{for(i=NF+1;i<=4;i++)$i="  "}7' file
i1, 12, 15,
i2, 00, 01,
i3,   ,   ,
i4, 18, 21, 36

$awk'开始{FS=OFS=“,”}NF一个用于GNU awk。它处理文件两次。在第一次运行时,它确定最大字段数,在第二次运行时,它将“空”(两个空格)字段添加到末尾:

$ awk '
BEGIN {
    FS=OFS=", "            # field separators
}
NR==FNR {                  # first run
    if(maxnf<NF)           # find the biggest NF
        maxnf=NF
    next
}
NF<maxnf {
    nf=NF+1                # store NF+1 for for
    NF=maxnf               # reset the NF
    for(nf;nf<=NF;nf++)    # process the new fields
        $nf="  "
}1' file file              # output records
使用

你有

i1, 12, 15,
i2, 00, 01,
i3,,,
i4, 18, 21, 36

如果输出行的顺序无关紧要,则使用
排序的另一个awk

$ awk -F"," ' {print NF "," $0 } ' tane.txt  | sort -k1 -nr | awk -F, ' { if(NR==1) mx=NF;for(i=2;i<mx;i++) {$i=length($i)?$i:" "; printf "%s,", $i} print $i } '
i4, 18, 21, 36
i2, 00, 01,
i1, 12, 15,
i3, , ,

$

不管好坏您所需的
i3、、、
输出不是CSV文件的标准
i3、、、
将是正确的格式,否则
i3
之后的单元格值为3个空格,而不是通常的空单元格。为什么您希望未填充的单元格有三个空格,而不是正常的空值,当以数字形式导出到CSV时,将逗号直接放在彼此后面会产生空值?@user3439894感谢您提出这个问题。输出可以是
i3、、、
。我将空格放在上面的“期望输出”中,只是为了澄清我希望每行的列数相同(即逗号)。虽然这些空格并没有真正影响我对CSV的下游使用,但我确实编辑了@james brown的答案,删除了这些空格供我自己使用。添加空格并不能说明你不想做什么,而是引入了错误的数据!AFAIC您的输入和输出格式都不正确,并且包含错误的数据,因为实际数据之间的唯一字符应该是分隔符,在本例中是逗号。@user3439894同意。为了揭示更多信息,我的实际数据只是以制表符分隔,而不是逗号+空格分隔。但在将来,我会记住CSV应该只使用分隔符(例如逗号)分隔数据。
i1, 12, 15,
i2, 00, 01,
i3,,,
i4, 18, 21, 36
$ awk -F"," ' {print NF "," $0 } ' tane.txt  | sort -k1 -nr | awk -F, ' { if(NR==1) mx=NF;for(i=2;i<mx;i++) {$i=length($i)?$i:" "; printf "%s,", $i} print $i } '
i4, 18, 21, 36
i2, 00, 01,
i1, 12, 15,
i3, , ,

$
$ cat tane.txt
i1, 12, 15
i2, 00, 01
i3
i4, 18, 21, 36

$