csv - 如果数据中不存在分隔符值,则删除双引号
问题描述
给出了一个输入文件,其中的每一行都包含每列的引号和回车符/换行符。
如果该行包含新行,则将其附加在引号内的同一行中,例如第 1 行
如果 delimiter(,) 不存在,则删除每列的双引号。
删除回车符 ie(^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
但我没有达到我下面要求的最终输出
解决方案
使用库来解析 CSV 文件。除了总是想在这里使用库之外,您还有非常具体的原因,嵌入式换行符和分隔符。
在 Perl 中,一个好的库是Text::CSVText::CSV_XS
(如果安装了它会包装)。一个基本的例子
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);
}
评论
构造函数中的
binary
选项是处理嵌入数据的换行符将一行读入数组引用
$row
后,我会使用简单的正则表达式删除每个字段中的换行符。无论如何,如果需要,请改进它作品的修剪
$row
如下。在foreach
循环中,每个元素都由循环变量起别名,因此如果更改,数组也会更改。我使用 default where elements are aliased by$_
,正则表达式更改因此$row
更改。我喜欢这个紧凑的快捷方式,因为它的外观非常独特,我可以从房间的另一头看出一个数组正在就地更改,因此可以将其视为一种惯用语。但如果它实际上令人困惑,请务必写出一个完整且正确的循环
处理后的输出打印到
STDOUT
. 或者,打开一个输出文件并将该文件句柄传递给say
(或print
在较旧的模块版本中),以便输出直接到该文件
以上打印,用于问题中提供的示例输入
姓名、地址、年龄 内存,“abcd,def”,10 abhi,xyz,25 广告,“拉姆,约翰”,35
推荐阅读
- php - 按指定的一组值对 php 多维数组进行排序
- c - Big-endian 或 Little-endian 对结构成员的影响是什么?
- javascript - 使用 Gulp 输出下面的一个目录
- angular - punycode 用箭头函数编译,无法在 ie 11 中渲染
- aurelia - 表单在不同的viewmodel中提交数据预览
- php - 使用 guillotine 库在服务器上裁剪和旋转图像
- regex - 删除第二个和第三个冒号之间的文本
- android - 无法解析符号 ThemeOverlay
- azure - Azure 队列存储 - 没有删除的 SAS 权限
- unity3d - Unity 中自定义着色器的 GPU 实例化问题