【发布时间】:2010-09-30 10:03:11
【问题描述】:
我只是 Perl 的初学者,在使用 Perl 脚本过滤列时需要一些帮助。 我在一个文件中有大约 10 列用逗号分隔,我需要在该文件中保留 5 列并删除该文件中的所有其他列。我们如何实现这一目标?
非常感谢任何人的帮助。
干杯, 尼尔
【问题讨论】:
-
请提供更多细节,尤其是各列的区别。数据的一个例子会很棒。
我只是 Perl 的初学者,在使用 Perl 脚本过滤列时需要一些帮助。 我在一个文件中有大约 10 列用逗号分隔,我需要在该文件中保留 5 列并删除该文件中的所有其他列。我们如何实现这一目标?
非常感谢任何人的帮助。
干杯, 尼尔
【问题讨论】:
查看Text::CSV(或Text::CSV_XS)以在 Perl 中解析 CSV 文件。它在CPAN 上可用,或者如果您使用 Linux 或其他类 Unix 操作系统,您也可以通过包管理器获得它。在 Ubuntu 中,该软件包称为 libtext-csv-perl。
它可以处理像被引用的字段这样的情况,因为它们包含逗号,这是简单的拆分命令无法处理的。
【讨论】:
CSV 是一种定义不明确的复杂格式(引号、逗号和空格的奇怪问题)。寻找a library,它可以为您处理细微差别,并为您提供便利,例如按列名索引。
当然,如果您只是想用逗号分割文本文件,那么@Pax 的解决方案就是您的最佳选择。
【讨论】:
使用 split 将行分开,然后输出您想要的行(比如每隔一列),创建以下 xx.pl 文件:
while(<STDIN>) {
chomp;
@fields = split (",",$_);
print "$fields[1],$fields[3],$fields[5],$fields[7],$fields[9]\n"
}
然后执行:
$ echo 1,2,3,4,5,6,7,8,9,10 | perl xx.pl
2,4,6,8,10
【讨论】:
如果您谈论的是 Windows 中的 CSV 文件(例如,从 Excel 生成的文件),您需要小心处理本身包含逗号但用引号括起来的字段。
在这种情况下,简单的 split 将不起作用。
【讨论】:
或者,您可以使用标准库中的Text::ParseWords。添加
use Text::ParseWords;
到上面 Pax 示例的顶部,然后替换
my @fields = parse_line(q{,}, 0, $_);
用于拆分。
【讨论】:
您可以使用 Perl 的一些内置运行时选项在命令行上执行此操作:
$ echo "1,2,3,4,5" | perl -a -F, -n -e 'print join(q{,}, $F[0], $F[3]).qq{\n}'
1,4
以上将 -a(utosplit) 使用 -F(ield) 逗号。然后它将加入您感兴趣的字段并将它们打印出来(使用行分隔符)。这假定没有嵌套逗号的简单数据。我使用不可打印的字段分隔符 (\x1d) 执行此操作,所以这对我来说不是问题。
更多详情请见http://perldoc.perl.org/perlrun.html#Command-Switches。
【讨论】:
去寻找并没有找到一个很好的兼容 csv 的过滤器程序,它不仅可以灵活地用于其中一个,因此我写了一个。享受吧。
基本用法是:
bash$ csvfilter [-r
【讨论】:
除了这里的人所说的处理逗号分隔文件之外,我想指出,可以使用数组切片和/或映射来提取偶数(或奇数)数组元素:
@myarray[map { $_ * 2 } (0 .. 4)]
希望对你有帮助。
【讨论】:
我个人最喜欢的 CSV 方法是使用 AnyData module。它似乎使事情变得非常简单,并且可以很容易地删除命名列。 Take a look on CPAN.
【讨论】:
这回答了一个更大的问题,但似乎是一个很好的相关信息。
unix cut 命令可以做你想做的事(还有更多)。一直是reimplemented in Perl。
【讨论】: