Bash-删除包含空值的行时出现问题

Bash-删除包含空值的行时出现问题,bash,Bash,我有一个.csv文件,需要按以下方式修改:对于文件中的每一列,检查该列是否包含任何空条目。如果是,它将从文件中删除。否则,该列将保持不变。我尝试使用以下脚本解决此问题: cp file-original.csv file-tmp.csv for (( i=1;i<=65;i++)); do for var in $(cut -d, -f$i file-tmp.csv); do if [ -n $var ]; then continue else

我有一个.csv文件,需要按以下方式修改:对于文件中的每一列,检查该列是否包含任何空条目。如果是,它将从文件中删除。否则,该列将保持不变。我尝试使用以下脚本解决此问题:

cp file-original.csv file-tmp.csv

for (( i=1;i<=65;i++)); do
  for var in $(cut -d, -f$i file-tmp.csv); do
    if [ -n $var ]; then
      continue
    else
      cut -d, --complement -f$i file-tmp.csv > file-tmp.csv
      break
    fi
  done
done
cp file-original.csv file-tmp.csv
对于((i=1;i文件-tmp.csv
打破
fi
完成
完成

我假设问题在于将每次迭代的结果保存到一个也在迭代的文件(
文件tmp.csv
)中。但是,我不确定如何避免这种情况。

您必须像中一样使用临时文件

cut-d,--complete-f$i file-tmp.csv>tmp.csv&&mv tmp.csv file-tmp.csv
对于$(cut-d,-f$i file tmp.csv)中的var来说是有缺陷的:您将无法检测到这样的空行,因为分词只会跳过它

通过跟踪要删除的列,然后一次性删除它们,您可以首先避免所有文件副本:

{1..65}中i的
;do
如果grep-q'^$'文件-tmp.csv
这使用grep来查看列是否包含空行,从而避免了慢循环和分词错误

在for循环之后,
drop
数组包含我们要删除的所有列号,
$(IFS=,;echo“${drop[*]}”)
将它们打印为逗号分隔的列表。

$cat foo.csv
$ cat foo.csv
a,,c,d
a,b,,d

$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR {
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        if ($inFldNr ~ /^$/) {
            skip[inFldNr]
        }
    }
    next
}
FNR==1 {
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        if ( !(inFldNr in skip) ) {
            out2in[++numOutFlds] = inFldNr
        }
    }
}
{
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        inFldNr = out2in[outFldNr]
        printf "%s%s", $inFldNr, (outFldNr<numOutFlds ? OFS : ORS)
    }
}

$ awk -f tst.awk foo.csv foo.csv
a,d
a,d
a、 ,c,d a、 b,d $cat tst.awk 开始{FS=OFS=“,”} NR==FNR{
对于(inFldNr=1;inFldNr查看您的问题,我发现了一个非常简单的答案,只使用
grep
命令并输出到临时文件。 假设您的CSV文件名为
test.CSV
。下面创建一个文件
test1.CSV
,该文件已删除包含
null
值的所有行:

grep -v null test.csv > test1.csv

-v
选项反转
grep
命令的输出,回显内部不包含
null
的行。输出可以转发到另一个文件,然后您可以替换原始的
test.csv
文件。

您必须使用一个临时文件,例如,请参阅。我将在ap中添加一个带有替代项的答案首先避免复制的方法。请参阅。有关允许引用字段的CSV文件,您应该使用带有适当CSV解析库的通用语言。