Csv 如果数据中不存在分隔符值,请删除双引号
给出了一个输入文件,其中每行包含每列的引号和回车/换行字符Csv 如果数据中不存在分隔符值,请删除双引号,csv,perl,awk,sed,Csv,Perl,Awk,Sed,给出了一个输入文件,其中每行包含每列的引号和回车/换行字符 如果该行包含新行,则必须在同一行中追加新行 引号内的行,例如第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获得以下输出 na
- 如果该行包含新行,则必须在同一行中追加新行 引号内的行,例如第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
但是我没有实现最终输出。下面我需要的是使用gnu awk处理逗号分隔的文件
它不会对不包含双引号的字段执行任何操作。
FPAT
是使用gnu awk的方法,它处理逗号分隔的文件
它不会对不包含双引号的字段执行任何操作。使用库解析CSV文件。除了总是想在这里使用库之外,你也有非常具体的原因,嵌入了换行符和分隔符 在Perl中,一个好的库是(如果安装了,它包装
Text::csvxs
)。一个基本的例子
use warnings;
use strict;
use feature 'say';
use Text::CSV;
my $file = shift or die "Usage: $0 file.csv\n";
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $fh, '<', $file or die "Can't open $file: $!";
while (my $row = $csv->getline($fh)) {
s/\n+//g for @$row;
$csv->say(\*STDOUT, $row);
}
使用库解析CSV文件。除了总是想在这里使用库之外,你也有非常具体的原因,嵌入了换行符和分隔符 在Perl中,一个好的库是(如果安装了,它包装
Text::csvxs
)。一个基本的例子
use warnings;
use strict;
use feature 'say';
use Text::CSV;
my $file = shift or die "Usage: $0 file.csv\n";
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $fh, '<', $file or die "Can't open $file: $!";
while (my $row = $csv->getline($fh)) {
s/\n+//g for @$row;
$csv->say(\*STDOUT, $row);
}
使用
perl
,请尝试以下操作:
perl -e '
while (<>) {
s/\r$//; # remove trailing CR code
$str .= $_;
}
while ($str =~ /("(("")|[^"])*"\n?)|((^|(?<=,))[^,]*((?=,)|\n))/g) {
$_ = $&;
if (/,/) { # the element contains ","
s/\n//g; # then remove newline(s) if any
} else { # otherwise remove surrounding double quotes
s/^"//s; s/"$//s;
}
push(@ary, $_);
if (/\n$/) { # newline terminates the element
print join(",", @ary);
@ary = ();
}
}' sample.txt
使用
perl
,请尝试以下操作:
perl -e '
while (<>) {
s/\r$//; # remove trailing CR code
$str .= $_;
}
while ($str =~ /("(("")|[^"])*"\n?)|((^|(?<=,))[^,]*((?=,)|\n))/g) {
$_ = $&;
if (/,/) { # the element contains ","
s/\n//g; # then remove newline(s) if any
} else { # otherwise remove surrounding double quotes
s/^"//s; s/"$//s;
}
push(@ary, $_);
if (/\n$/) { # newline terminates the element
print join(",", @ary);
@ary = ();
}
}' sample.txt
这可能适用于您(GNU-sed):
解决方案分为两部分:
注意:假设字段不包含双引号。如果是这种情况,则需要修改第一步的条件,并且需要满足字段中的双引号。要删除
^M
您可以执行dos2unix sample.txt
这是CSV格式的数据,您可能不想删除引号。这感觉像是一场灾难。告诉我们您真正想要完成的是什么,即您为什么认为需要删除引号。cat yourfile | dos2unix | tr-d'
David tr删除双引号会删除所有引号?您确定有^M
s(\r
s)在引用字段内?例如,如果这是一个从Excel导出的文件,那么每个记录的末尾都会有\r\n
,但在引用字段内,换行符只会是\n
,而不是\r\n
。在任何情况下,要使用awk处理它,请参见。要摆脱^M
,您可以执行dos2unix sample.txt
这是CSV格式的数据,您可能不想删除引号。这感觉像是一个问题。告诉我们您真正想要完成的是什么,即您认为需要删除引号的原因。cat yourfile | dos2unix | tr-d'
David tr删除双引号会删除所有引号?您确定有^M
吗(\r
s)在引用字段内?例如,如果这是一个从Excel导出的文件,那么每条记录的末尾都会有\r\n
,但在引用字段内,换行符只会是\n
,而不是\r\n
。在任何情况下,要用awk处理它,请参见。谢谢您的详细解释。您能给我解释一下最后一段吗awk-v FPAT=“([^,]+)|”(\“[^\“]+\”)-v OFS=,“{for(i=1;i@user1485267添加了更多的信息谢谢你的信息。但是第三个功能不起作用,我得到了与第二步相同的结果。目前我正在尝试的awk版本是GNU awk 3.1。7@EdMorton这就是为什么我添加了两个awk:)谢谢你的详细解释。你能给我解释一下你应用的最后一种模式吗。awk-v FPAT=“([^,]+)|(\“[^\”]+\”)-v OFS=,“{for”(i=1;i@user1485267添加了更多的信息谢谢你的信息。但是第三个功能不起作用,我得到了与第二步相同的结果。目前我正在尝试的awk版本是GNU awk 3.1。7@EdMorton这就是为什么我添加了两个awk:)谢谢你的解决方案。如果我不确定将来会有多少列。在这种情况下,你提供的解决方案是不可行的。@user1485267我仔细考虑了这个问题,请参阅修订的简化解决方案。谢谢你的解决方案。如果我不确定将来会有多少列。在这种情况下,你提供的解决方案是不可行的。@user1485267我仔细考虑了这个问题,请参阅修改后的简化解决方案。谢谢tshino占用您的时间。谢谢tshino占用您的时间。
name,address,age
ram,"abcd,def",10
abhi,xyz,25
ad,"ram,John",35
perl -e '
while (<>) {
s/\r$//; # remove trailing CR code
$str .= $_;
}
while ($str =~ /("(("")|[^"])*"\n?)|((^|(?<=,))[^,]*((?=,)|\n))/g) {
$_ = $&;
if (/,/) { # the element contains ","
s/\n//g; # then remove newline(s) if any
} else { # otherwise remove surrounding double quotes
s/^"//s; s/"$//s;
}
push(@ary, $_);
if (/\n$/) { # newline terminates the element
print join(",", @ary);
@ary = ();
}
}' sample.txt
name,address,age
ram,"abcd,def",10
abhi,xyz,25
ad,"ram,John",35
sed ':a;/[^"]$/{N;s/\n//;ba};s/"\([^",]*\)"/\1/g' file