代码之家  ›  专栏  ›  技术社区  ›  Megiddo

Perl,读取文本文件,保存列以使用列元素打开其他文件

  •  2
  • Megiddo  · 技术社区  · 8 年前

    我有一个文本文件,标签分开,如下所示:

    <这是标题

    col1 col2 col3

    布拉布拉布拉文本2。喋喋不休
    布拉布拉布拉文本3。喋喋不休

    我希望能够提取某些元素(列),在本例中仅提取文字text1。文本,文本2。txt和text3。txt。我想稍后使用它们打开具有这些名称的文件。

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my @fields;
    my ($column1, $column2, $column3);
    
    my $text = "text.txt";
    
    open(FILE, $text) or die "Could not read from $text, program halting.";
    
    my @files;
    
    while(<FILE>)
    {
      chomp;
       /^</ and next;
       /^\s*$/ and next;
       /line*/ and next;
    
      ($column1, $column2, $column3) = split('\s', $_);
    
    #PRINT ONE
    #print $column2, "\t";
    
    
    }
    #PRINT TWO
    print $column2, "\t";
    
    close FILE;
    

    如果我用#print ONE按注释打印,我只会得到正确的版本作为输出,包括所有三个元素,但当我试图将其保存在另一个变量中或写入文件时,只剩下“text3.txt”。 如果我像#print TWO那样打印,我只得到一个元素,相同的text3。txt。 我该如何从中学习?我从这个网站上尝试了很多代码,但到目前为止没有结果。非常感谢。

    1 回复  |  直到 8 年前
        1
  •  2
  •   stevieb    8 年前

    这是因为您覆盖了 $column2 在每次循环中,当你离开循环后,你得到了最后一个结果( text3.txt

    您可以在循环中写入文件,如本例所示。它还显示了如何使用正确的3-arg open

    use warnings;
    use strict;
    
    my $input_file = 'data.txt';
    my $output_file = 'out.txt';
    
    open my $fh, '<', $input_file or die $!;
    open my $wfh, '>', $output_file or die $!;
    
    while (<$fh>){
        chomp;
        next if /^\</;
        next if /^\s*$/;
    
        my ($c1, $c2, $c3) = split /\s/, $_;
    
        print $wfh "$c2\n";
    }
    

    将其作为输入文件:

    < this is a header
    
    col1 col2 col3
    blablabla text1.txt blablabla
    blablabla text2.txt blablabla
    blablabla text3.txt blablabla
    

    col2
    text1.txt
    text2.txt
    text3.txt
    

    ...在输出文件中。你必须弄清楚如何过滤第一行。

    use warnings;
    use strict;
    
    my $input_file = 'data.txt';
    
    open my $fh, '<', $input_file or die $!;
    
    my @saved_entries;
    
    while (<$fh>){
        chomp;
        next if /^\</;
        next if /^\s*$/;
        push @saved_entries, (split /\s/, $_)[1];
    }
    
    for (@saved_entries){
        print "$_\n";
    }
    

    注意,我在这里过于冗长,尽可能接近操作代码。