使用 bash 脚本从 csv 文件中删除空列

使用 bash 脚本从 csv 文件中删除空列

寻找某种方法来查看 csv 文件并删除后续行中没有值的列(包括标题)。

也许如果我想从下面删除列 Test03,包括第一行的 Test03。

Test01,Test02,Test03,Test04  
11,22,,44  
11,22,,44  
11,22,,44  
11,22,,44  
11,22,,44  
11,22,,44  

答案1

这是一个 awk 解决方案,其执行结果与哪些列为空无关(忽略标题)。

awk -F, '{
    a[NR]=$0
}NR>1{
    for (i=1;i<=NF;i++) 
        if(length($i)!=0) b[i]++
}END{
    for (k=1;k<=NR;k++) { 
        LINE="" ; 
        split(a[k],c,",") ; 
        for (j=1;j<=NF;j++) 
            if(b[j]>0) 
                LINE=LINE","c[j] ; 
        print substr(LINE,2,length(LINE)-1)
    } 
}' test.csv

答案2

在当前情况下,您只需执行以下操作:

sed 's/,,/,/g' test.csv > new.csv

这会将所有双逗号替换为一个,从而有效地删除空列。请注意,您需要自己从标题中删除该列。

答案3

如果您想要删除可能非空的列(包括标题中的列),请使用“cut”命令:

cut -d , -f 1,2,4 test.csv > new.csv

答案4

这需要一个程序,而不是一个快捷命令。最好的方法是,正如 Andrew Medico 所建议的,使用一个合适的 CSV 解析器(如果perl你有Text::CSV)。

不过,我想我应该编写一个perl可以在非常简单的情况下工作的脚本:

perl -F, -lane 'if($.==1){@a=@F;next};for($i=0;$i<@F;$i++){if($F[$i]!=""){push @c,$F[$i];push @b,$i}}if(@a){foreach(@b){push @t,$a[$_]};print join(",",@t);undef @a}print join(",",@c);undef @c' file.csv

这将保存第一行并继续查看下一行是否有空字段。然后它只打印相关标题,跳过所有行中的空字段。

请注意,它不处理引号字符串内的逗号。但是,它可以:

Test01,Test02,Test03,Test04
11,22,,44
11,22,,44
11,22,,44
11,22,,44
11,22,,44
11,22,,44

进入:

Test01,Test02,Test04
11,22,44
11,22,44
11,22,44
11,22,44
11,22,44
11,22,44

相关内容