使用bash在csv中输出带有一个非空列的行

时间:2014-11-07 10:32:31

标签: bash csv awk

给定一个csv文件,我只想输出只有一个非空列的行。

输入文件

"a","b","c"
"d","",""

输出:

"d","",""

这可以用bash完成吗?

7 个答案:

答案 0 :(得分:3)

更简单的awk解决方案可以

$ awk '/^("",)*"."(,"")*$/' inputFile
"d","",""

它的作用

  • /^("",)*"."(,"")*$/个模式匹配为

    • ("",)空列数

    • "."后跟 ONE 非空列

    • (,"")后面还有空列数

  • 未指定任何操作,因此采用默认操作来打印整个记录

修改

如果列中有多个字母

$ awk '/^("",)*"[^"]+"(,"")*$/' input
"d","",""

感谢Jotne

答案 1 :(得分:2)

您可以使用sed

sed -n '/^[",]*[^",]*[",]*$/p' file

要确保它与空行不匹配,我们可以添加+

sed -n '/^[",]*"[^",]\+"[",]*$/p' file

它返回:

"d","",""

这是一个检查是否有一个,只有一个,阻止这些字符之间的",不同的字符。 -n禁止打印,而p打印完成条件的行。

答案 2 :(得分:2)

您可以使用gsub()计算找到空字段的次数,然后从NF中减去并测试等于1。这是使用GNU AWK和FPAT variable的一种方式:

awk 'BEGIN { FPAT = "([^,]+)|(\"[^\"]+\")" } NF - gsub(/""/, "&") == 1' file

如果您没有嵌入式逗号,则只需编写:

awk -F, 'NF - gsub(/""/, "&") == 1' file

答案 3 :(得分:1)

通过sed。

$ sed -rn '/^(".[^"]*"(,"")*|""(,"")*,".[^"]*"(,"")*)$/p' file
"d","",""

第一部分".[^"]*"(,"")*匹配这些类型的字符串"A","","",其中第二部分""(,"")*,".[^"]*"(,"")*将匹配这些类型的字符串格式"","","A"

示例:

$ cat file
"a","b","c"
"d","",""
"","","A"
"A","","A"
"","A",""
"","A","A"
"A","A",""
$ sed -rn '/^(".[^"]*"(,"")*|""(,"")*,".[^"]*"(,"")*)$/p' file
"d","",""
"","","A"
"","A",""

答案 4 :(得分:1)

一种简单的方法,假设CSV文件中没有字段包含逗号:

awk -F '[",]+' '{n=0;for(i=2;i<NF;++i)$i~/^$/||++n}n==1' file.txt

将输入字段分隔符设置为一个或多个双引号和逗号。循环遍历所有字段,为每个非空字段递增n。如果总数正好为1,则打印该行。

循环从字段2转到NF-1的原因是第一个和最后一个字段位于您感兴趣的部分之前和之后。

非常相似但又短得多:

awk -F ',' '{n=0;for(i=1;i<=NF;++i)$i~/""/||++n}n==1' file.txt

使用逗号作为字段分隔符,并为包含n的任何字段增加""。在这种情况下,循环遍历每个字段。

答案 5 :(得分:0)

这个grep应该能够解决这个问题:

grep -E '^("",)*"[^"]+"(,"")*$' file
"d","",""

答案 6 :(得分:0)

只需将该行拆分为字段并计算有多少非空:

$ awk -F'^"|","|"$' '{c=0; for (i=2; i<NF; i++) if ($i != "") ++c} c==1' file
"d","",""

循环从2开始并在NF-1结束,因为没有必要检查在第一个和最后一个“真实”字段之前(即^"之前和{之后}之前将始终存在的空字段{1}})当使用包含字符串开头("$)和字符串结尾(^)RE元字符的FS拆分行时。

如果您想检查不同的非空字段数,只需将您比较的数字$更改为:

c

$ cat file
"a","b","c"
"d","",""
"e","","f"
"","",""