如何删除具有空字段的行?

如何删除具有空字段的行?

我有一个 CSV 文件,其中包含多列、逗号“,”分隔和行数。
有些行有一个或两个空字段“列”。我如何在单独的文件中进行识别和/或删除带有一个或多个空列的行awk命令。

例子

aaaa,bbbb,cccc,dddd,
,bbbb,cccc,dddd,
aaaa,,cccc,dddd,
aaaa,,,dddd,
,,,dddd,

“, ,”表示空列。我尝试了这个命令,但它不起作用!

awk -F, '$1,4~/^$/' filename 

预期输出应该只是:

aaaa, bbbb, cccc, dddd,

答案1

awk -F, '{for(i=1;i<=NF;i++)if($i==""){next}}1' inputfile

答案2

使用米勒 ( mlr)和它的filter子命令丢弃至少包含一个空字段的每条记录:

mlr --csv -N filter 'for (k,v in $*) { is_empty(v) { false; break } true }' file.csv

这会将数据读取为无标头 CSV。循环for针对每个记录运行,如果返回filter则操作立即丢弃该记录is_empty(v)真的

鉴于问题中的测试数据,此处给出的命令不会输出任何内容,因为每条记录至少包含一个空字段。

如果您只想检查前四个字段,请使用测试来k确保您只测试前四个字段是否为空:

mlr --csv -N filter 'for (k,v in $*) { k <= 4 && is_empty(v) { false; break } true }' file.csv

答案3

假设这是一个简单的 CSV 文件(没有引用、没有标题、没有多行字段):

perl -F, -e 'print unless grep {$_ eq ""} @F[0..3]' your-file

将删除第一到第四字段中任何一个为空的行(正如您的 awk 尝试建议您想要做的那样)。

虽然该代码很紧凑,但它会冗余地检查所有 4 个字段,即使它一旦发现一个字段为空就会停止检查。

awk -F, '$1 != "" && $2 != "" && $3 != "" && $4 != ""' file.csv

即使不那么紧凑也不会有问题

请注意,两者都会删除字段少于四个的行。

答案4

使用(以前称为 Perl_6)

~$ raku -ne '.put unless grep {.chars == 0}, .split(",")[0..*-2]'  file

或者:

~$ raku -ne 'given .split(",", :skip-empty) {.join(",").put if .elems > 3}'  file

上面的第一个答案与 @StéphaneChazelas 给出的 Perl 答案非常相似(谢谢你,Stéphane!)。由于行以逗号结尾(可以解释为尾随空白列),因此[0..*-2]使用索引来删除最后一个(空)元素。此代码保留包含所有已填充列的行(最后一个空列除外),并且如果找到空白列,则会删除行即使前 4 个字段。.split(",")[0..3]如果您想将要求限制为前四个字段(元素),请使用此选项。

注意,*-1是 Raku 中类似数组结构的最后一个元素,而类似的东西[0..*]也有效(意味着'把所有东西都给我')。 Raku 也有“禅宗切片”,因此也是.split(",")[]有效的语法。

第二个答案使用了这样一个事实:Raku 的split例程有一个:skip-empty参数(即“副词”),可以代替grepping for .chars == 0。因此,您需要决定输出中需要多少列。这里.elems > 3要求至少 4 列。

从技术上讲,第二个答案是正确的答案,因为第一个答案将尾随逗号保留在原处,而第二个答案则将其删除。

输入示例:

aaaa,bbbb,cccc,dddd,
,bbbb,cccc,dddd,
aaaa,,cccc,dddd,
aaaa,,,dddd,
,,,dddd,

示例输出(第一个答案):

aaaa,bbbb,cccc,dddd,

示例输出(第二个答案):

aaaa,bbbb,cccc,dddd

https://docs.raku.org
https://raku.org

相关内容