" grep的"包含多行字段的csv文件?

时间:2017-05-11 09:59:28

标签: shell csv grep multiline

FILE.CSV:

XA90;"standard"
XA100;"this is
the multi-line"
XA110;"other standard"

我想要" XA100"像这样的条目:

grep XA100 file.csv

获得此结果:

XA100;"this is
the multi-line"

但grep只返回一行:

XA100;"this is

source.csv包含3个条目。 " XA100"条目包含多行字段。 并且grep似乎不是" grep"的正确工具。 CSV文件包括多行字段。

你知道如何完成这份工作吗?

编辑:真实世界文件包含许多列。研究的术语可以在任何列中(不是在行的开头,也不是在字段的开头)。所有字段都由"封装。任何字段都可以包含从1行到任意行的多行,这是无法预测的。

5 个答案:

答案 0 :(得分:1)

试一试这行:

awk '/^XA100;/{p=1}p;p&&/"$/{p=0}' file

我扩展了你的例子:

kent$  cat f
XA90;"standard"
XA100;"this is
the
multi-
line"
XA110;"other standard"

kent$  awk '/^XA100;/{p=1}p;p&&/"$/{p=0}' f
XA100;"this is
the
multi-
line"

答案 1 :(得分:0)

在你提到的评论中:在真实世界文件中,每一行都以" 开头。我假设它们也以"结束并向您展示:

测试文件:

$ cat file
"single line"
"multi-
lined"

代码和输出:

$ awk 'BEGIN{RS=ORS="\"\n"} /single/' file
"single line"
$ awk 'BEGIN{RS=ORS="\"\n"} /m/' file
"multi-
lined"

您还可以参数化搜索:

$ awk -v s="multi" 'BEGIN{RS=ORS="\"\n"} match($0,s)' file
"multi-
lined"

答案 2 :(得分:0)

尝试: 解决方案1:

awk -v RS="XA" 'NR==3{gsub(/$\n$/,"");print RS $0}'  Input_file

将记录分隔符设置为字符串XA,然后在此处查找第3行,然后使用NULL替换$ \ n $(这将删除行尾的额外行)。然后使用当前行打印记录分隔符。

解决方案2:

awk '/XA100/{print;getline;while($0 !~ /^XA/){print;getline}}'  Input_file

查找字符串XA100然后打印当前行并使用getline转到下一行,然后使用while循环然后运行并打印行直到从XA开始一行。

答案 3 :(得分:0)

如果此文件是从MS-Excel或类似文件导出的,则行以\r\n结尾,而引号内的换行符只是\n s,那么您只需要:

$ awk -v RS='\r\n' '/XA100/' file
XA100;"this is
the multi-line"

以上使用GNU awk进行多字符RS。在某些平台上,例如cygwin,你必须添加-v BINMODE=3所以gawk看到\r而不是它们被底层C基元剥离。

否则,如果没有真正的CSV解析器(awk目前没有,但正在为GNU awk工作),解析CSV文件是非常困难的,但你可以这样做(再次使用GNU awk for multi-char) RS):

$ cat file
XA90;"standard"
XA100;"this is
the multi-line"
XA110;"other standard"

$ awk -v RS="\"[^\"]*\"" -v ORS= '{gsub(/\n/," ",RT); print $0 RT}' file
XA90;"standard"
XA100;"this is the multi-line"
XA110;"other standard"

用空白字符替换引号中的所有换行符,然后将其作为常规的每行记录文件处理。

答案 4 :(得分:0)

使用PS响应,这适用于小例子:

sed 's/^X/\n&/' file.csv | awk -v RS= '/XA100/ {print}'

对于我的真实世界CSV文件,包含许多列,在任何地方都有研究过的术语,未知的多行数,带字符"由""取代,多行行以"开头,所有字段由"封装,这有效。注意排除第二个字符"在sed部分:

sed 's/^"[^"]/\n&/' file.csv | awk -v RS= '/RESEARCH_TERM/ {print}'

因为任何条目的第一列都不能以""开头。第一列总是看起来像" XXXXXXXXX",其中X是任何字符但是"。

感谢大家的回复,也许其他解决方案正在运行,具体取决于您使用的CSV文件格式。