csv 在Perl中,如何从给定的字符串开始处理文件?

c86crjj0  于 2023-06-19  发布在  Perl
关注(0)|答案(2)|浏览(145)

我需要打开一个非常混乱的csv文件(我的意思是数据之间的空白列和行,我只需要一些列中的数据),只有当它到达带有“信息A”或“信息A”的给定行时才开始将数据分配给列(文件是两种不同语言中的一种,但格式相同)。该表的格式大致如下:

(n) Name
(n) General info
(n) ID
(n) Contact
(n) General
(n)
(a) Information A
(a)
(a) Name
(a) one
(a) two
(a) three
(a)
(a) four
(a) five
(a) Total
(b) Information B
(b)
(b) Name

程序的基本大纲是为我写的,最初工作的第一部分额外的细节被指定为$part ='n '(如上面的(n)所示),而后面的“信息A”被指定为“a”,依此类推。然而,我想我可能删除了一些代码,这使得整个提取无法使用。我试着修复它,但已经看到做更多的损害比好,所以我试图从头开始,并希望学习一个更简单的方法来做这个过程中。
到目前为止,我的代码如下:

open (IN_F, "$file") or die "Can't open $file";

  my %file;

while (<IN_F>){

  my $line = $_;
     $line =~ s/\s*$//g;
     $line =~ s/\-//g;

  my $part='n';
     $part='a' if (substr($line,0,13) eq 'Information A');
     $part='b' if (substr($line,0,13) eq 'Information B');

  next if $part='a';
  last if substr($line,0,20) eq 'Litter Information B';

  print "$line\n";
}
exit;

我想打印出来的地方

Name
one
two
three
four
five
Total

我发现类似的问题有不同的解决方案;他们中的一些人使用了行号,但我的行号不是常量。另一种解决方案使用了‘..‘,我试过了,但我想我没有正确地应用它。
任何帮助将不胜感激!

9udxz4iz

9udxz4iz1#

下面的程序将按照您的要求执行。在您编写的每一个Perl程序的顶部都必须使用use strictuse warnings 'all',并使用my声明变量

use strict;
use warnings 'all';

my $file = 'information.txt';

open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!};

my $part = 'n';

while  ( <$fh> ) {

    if ( /(?:Information|Informasie) ([A-Z])/ ) {
        $part = $1;
        next;
    }

    print if $part eq 'A';
}

输出

Name
one
two
three
four
five
Total
mf98qq94

mf98qq942#

您需要做的是通读文件,直到看到要开始打印的行,然后打印到要停止打印的行:

#!/usr/bin/env perl

use strict;
use warnings;

while (my $line = <DATA>) {
    if ( $line =~ / Information A/ .. $line =~ / Total/ ) {
        print do { $line =~ s/^\(.\)\s+//; $line };
    }
}

__DATA__
(n) Name
(n) General info
(n) ID
(n) Contact
(n) General
(n)
(a) Information A
(a)
(a) Name
(a) one
(a) two
(a) three
(a)
(a) four
(a) five
(a) Total
(b) Information B
(b)
(b) Name

从5.14开始,你可以使用s/...//r代替do块。
此外,如果文件很大,您不希望在看到要打印的最后一行之后继续阅读。如果是这种情况,您可以使用:

while (my $line = <DATA>) {
    if ( $line =~ / Information A/ .. $line =~ / (Total)/ ) {
        print $line =~ s/^\(.\)\s+//r;
        last if $1 and $1 eq 'Total';
    }
}

相关问题