关于数组:Perl,读取文本文件,保存列以使用列元素打开其他文件

Perl, reading text files, saving columns for using elements of columns to open other files

我有一个文本文件,使用制表符分隔,如下所示:

< this is a header

col1 col2 col3
blablabla text1.txt blablabla
blablabla text2.txt blablabla
blablabla text3.txt blablabla

我希望能够提取某些元素(列),在这种情况下,仅提取文字text1.txt,text2.txt和text3.txt。我想稍后使用它们打开具有这些名称的文件。
到目前为止,我的代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/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。
我该如何学习?我已经从该站点尝试了很多代码,但到目前为止都没有结果。谢谢。


之所以发生这种情况,是因为您在循环的每一遍都覆盖了$column2,然后在退出循环之后,得到了最后一个结果(text3.txt)。

您可以在此示例中显示的循环中写入文件。它还显示了如何使用带有词法文件句柄的正确的3-arg open

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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\
"
;
}

将此作为输入文件:

1
2
3
4
5
6
< this is a header

col1 col2 col3
blablabla text1.txt blablabla
blablabla text2.txt blablabla
blablabla text3.txt blablabla

产品:

1
2
3
4
col2
text1.txt
text2.txt
text3.txt

...在输出文件中。您必须理清如何过滤第一行。

您还可以将输出保存到循环内的数组中,然后稍后对其进行处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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"$_\
"
;
}

...然后可以将其写入文件或执行所需的操作。

请注意,我在这里过于冗长,以尽可能接近OP代码。