给定一个csv文件,我只想输出只有一个非空列的行。
输入文件
"a","b","c"
"d","",""
输出:
"d","",""
这可以用bash完成吗?
答案 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"
"","",""