给定一个输入文件,其中每行包含对每列的引号和回车/换行字符。
- 如果该行包含新行,则必须将其附加到引号内的同一行中,例如第1行
- 如果不存在分隔符(,),则删除每列的双引号。
- 删除回车符,即(^M)
例如,给定以下输入文件
"name","address","age"^M
"ram","abcd,^M
def","10"^M
"abhi","xyz","25"^M
"ad","ram,John","35"^M
我希望通过sed/perl/awk脚本/oneliner获得以下输出。
name,address,age
ram,"abcd,def",10
abhi,xyz,25
ad,"ram,John",35
解决方案,我已经厌倦了它到目前为止为附加与前一行
sed '/^[^"]*"[^"]*$/{N;s/\n//}' sample.txt
用于替换control-m字符
perl -pne 's/\\r//g' sample.txt
但是我没有达到我下面所要求的最终输出
4条答案
按热度按时间2g32fytz1#
使用一个库来解析CSV文件。除了总是想使用一个库来解析CSV文件外,你还有一些非常具体的原因,比如嵌入的换行符和分隔符。
在Perl中,一个好的库是Text::CSV(如果安装了
Text::CSV_XS
,它会 PackageText::CSV_XS
)。备注
binary
选项用于处理数据中嵌入的换行符$row
,我就用一个简单的正则表达式删除每个字段中的换行符。$row
的工作原理如下:在foreach
循环中,每个元素实际上都被循环变量别名化了,所以如果它被改变了,数组也会改变。我使用了默认值,其中元素被别名化了$_
,正则表达式改变了,所以$row
也改变了。我喜欢这种紧凑的快捷方式,因为它具有如此独特的外观,以至于我可以从房间的另一端看出阵列正在适当地更改;所以我认为这是一种习惯用法。但如果它实际上是混乱的,请尽一切手段写出一个完整的和适当的循环
STDOUT
。或者,打开一个输出文件并将该文件句柄传递给say
(在较早的模块版本中传递给print
),以便输出直接转到该文件上面的打印内容,用于问题中提供的示例输入
o0lyfsai2#
这可能对你有用(GNU sed):
解决方案分为两部分:
1.将断开的线连接成完整的线。
1.删除不包含逗号的字段两边的双引号。
如果当前行没有以双引号结尾,则追加下一行,删除换行符并重复。否则:删除不包含双引号或逗号的字段周围的双引号。
注意:假设字段不包含双引号。如果是这样,第一步的条件需要修改,字段中的双引号也需要考虑。
cuxqih213#
FPAT
是使用gnu awk
的方法,它处理逗号分隔的文件。1.删除^m
1.清洁线
1.删除qute
。
一气呵成:
通常你设置文件分隔符
FS or F
来告诉你文件是如何被分隔的。FPAT="([^,]+)|(\"[^\"]+\")"
FPAT告诉你文件看起来像使用一个正则表达式。这个正则表达式很复杂,经常和CSV一起使用。(i=1;i<=NF;i++)
通过一个场在线路上循环。if($i!~",")
如果不包含逗号,则$i=substr($i,2,length($i)-2)
删除第一个和最后一个字符,即"
如果一个字段由于某种原因不包含
"
,这是更健壮的:它不会对不包含双引号的字段执行任何操作。
mefy6pfw4#
对于
perl
,请尝试以下操作:输出量: