在引用列中包含一些包含某些换行符的大型csv文件。我需要运行一个shell脚本,sed,awk,perl很好,只用空格替换引号内的换行符。必须保留行尾,并且我不知道列数或哪些字段可能包含这些嵌入的换行符。
对文件的进一步检查显示这是cat -v test_lf.csv
的结果[ [1,5,5],[2,3,4] ]
在csv文件中哪个excel显示换行符??M - ^ @?是
我想使用tr来替换空间中的任何内容。我该怎么办?这个序列是什么?
我现在发现该文件的一小部分在字符和十六进制中看起来如下所示。
"NORTH ?M-^@?OLMSTED"
"PORT?M-^@?ST?M-^@?LUCIE"
我在Mac上,文件是utf-8,我的语言环境是utf-8。看起来字节是交换的(小端),因此十六进制3431 3136在字符表示中是1463。因此,从此输出中的字节60开始,我们有:
东西,S,T,空白,东西,东西,L和十六进制这是:
53a8 e254 a880 554c,53是S,54是T,4c是L.因此,在T和L之间有一个e2,a8,80序列。这会在Excel电子表格字段中生成换行符。
如何通过空格查找和替换这些字节?
答案 0 :(得分:3)
我使用Perl模块Text::CSV
#!/usr/bin/perl
use strict;
use warnings;
use feature qw/say/;
use open IO => ':encoding(utf8)';
use open ':std';
use Text::CSV;
my $file = shift @ARGV;
open my $fh, "<", $file or die "cannot open $file: $!\n";
my $csv = Text::CSV->new({binary => 1});
while (my $row = $csv->getline($fh)) {
my @no_newlines = map {s/\n/ /g; $_} @$row;
$csv->combine(@no_newlines);
say $csv->string();
}
close $fh;
然后你可以运行它:
/path/to/csvfixer.pl file.csv > fixed.csv
答案 1 :(得分:0)
经过大量读取csv文件的十六进制转储后,查看Mac上的数字和PC上的Excel处理嵌入式中断的方式的差异,似乎找到并更改中断编码的简单可移植方式不是值得努力。如果包含拆分的数据字段用引号括起来,那么Excel将读取它们,就像读取R中的read.csv一样。
答案 2 :(得分:-1)
假设引号字符是双引号"
而转义字符也是双引号,如果在双引号数均为偶数时将所有换行符转换为空格,则可以使用sed执行此操作在模式空间。当数字是奇数时,你只需附加下一行。
sed ':a;/^\([^"]*"[^"]*"\)*[^"]*$/!{N;ba};y/\n/ /' file.csv
细节:
:a # define the label "a"
/^\([^"]*"[^"]*"\)*[^"]*$/! # if not an even number of quotes
{
N # append the next line to the pattern space
ba # go to label "a"
}
y/\n/ / # translate all line-feeds to spaces
如果报价未得到很好的平衡,则默认行为是不进行最后一次引用的部分。你可以改写它:
sed ':a;${y/\n/ /;s/$/"/};/^\([^"]*"[^"]*"\)*[^"]*$/!{N;ba};y/\n/ /' file.csv