如何在Perl中正确处理包含制表符分隔值的文件?

时间:2010-11-18 21:49:37

标签: perl

我是Perl的新手,对Perl的“正确”语法几乎一无所知。

我有一个文本文件,我每天都使用一个名单列表,以及我们用户的其他信息。此文件每天更改,有时在其中有两行(制表符分隔),其他时间有100行。

该文件也在一行中的6-9列数据之间变化。我已经整理了一个在选项卡上使用拆分功能的Perl脚本,但我遇到的问题是,如果我使用行 a ,其中有5列,然后添加第二行< em> b ,其中有6列,所有列都填充了数据。

我无法弄清楚如何让Perl看到该行只有5列数据并继续从该点向前解析文本文件。它继续,但输出奇怪地包装线。我该如何解决这个问题?我希望这是有道理的。

3 个答案:

答案 0 :(得分:4)

你必须发布一些代码和可能的一些示例数据,但这里是一个解析不同长度的行而没有问题的代码。

<强>脚本:

#!/usr/bin/perl
use strict;

while (<STDIN>)
{
    chomp;
    my @info = split("\t");
    print join(";", @info), "\n";
}

exit;

测试文件:

  jsmith  101     777-222-5555    Office 1        Building 1      Manager 
  aposse  104     777-222-5556    Office 2        Building 2      Stock Clerk 
  jbraza  105     777-222-5557    Office 3 
  mcuzui  102     777-222-5557    Office 3        Building 3      Cashier 
  ghines  107     777-222-5557    Office 3

<强>输出:

%> test.pl < file.txt
jsmith;101;777-222-5555;Office 1;Building 1;Manager
aposse;104;777-222-5556;Office 2;Building 2;Stock Clerk
jbraza;105;777-222-5557;Office 3
mcuzui;102;777-222-5557;Office 3;Building 3;Cashier
ghines;107;777-222-5557;Office 3

答案 1 :(得分:1)

您应该发布一些示例数据和代码,并根据代码当前的功能以及您希望它执行的操作来解释所需的行为。 split会为您提供与输入中一样多的字段。

#!/usr/bin/perl

use strict; use warnings;

while ( my $row = <DATA> ) {
    last unless $row =~ /\S/;
    chomp $row;
    my @cells = split /\t/, $row;
    print "< @cells >\n";
}

__DATA__
1 2 3 4 5
a b c d e f

答案 2 :(得分:1)

Text::CSV模块也可用于解析制表符分隔值。实际上,Text::CSV可以解析由任何字符分隔的值。

其POD的相关摘录:

  

模块接受字符串或   文件作为输入,可以使用任何   用户指定的字符为   分隔符,分隔符和转义符   它可能更好地称为ASV   (任何分离的价值)而不是   而不仅仅是CSV。

#!/usr/bin/env perl

use strict;
use warnings;

use Text::CSV;

my $csv = Text::CSV->new( { 'sep_char' => "\t" } );

open my $fh, '<', 'data.tsv' or die "Unable to open: $!";

my @rows;
while ( my $row_ref = $csv->getline($fh) ) {
    push @rows, $row_ref;
}

$csv->sep_char('|');
for my $row_ref (@rows) {
    $csv->combine(@$row_ref);
    print $csv->string(), "\n";
}