希望,有人可以帮我解决以下问题:
我有以下两个列表(一个是制表符分隔的):
chr \ t start \ t end \ t alt \ t ref \ t \ t *(其他列)
我的目标是使用perl脚本比较两个列表,基于colums中的值" start"," end"," alt"和" ref"。这意味着,如果这四个列中列表1中的行的值等于列表2的行中的条目,则列表1的整行应写入文件" common.txt"。对于基本脚本,我开始将列表1的内容写入数组:
#!/usr/local/bin/perl
use strict;
use warnings;
my @file1;
open (FILE, "< path_to_file") || die "Can not find file: $!\n";
while (defined(my $i = <FILE>) {
push (@file1, $i)
}
print "@file1\n"; #temporary added line to test for output
结果,创建了一个包含FILE所有条目的数组@ file1(很好,该数组包含FILE的值)。现在的问题是:如何指定上面提到的列。我试图将数组写入标量$ content,并希望使用
隔离第二列(开始)$content = @file1;
print "$content[1]\n";
但是(确实有道理),这些行给了我数组的元素[1],它是FILE的第二行。 合在一起:我使用while循环逐行将FILE的内容写入数组@ file1。如何提取定义的列的值? (注意:指定列的值未知,因此不能用于模式搜索)。
最佳, 脾气暴躁的
答案 0 :(得分:1)
这是对两个文件进行并行迭代的更好方法:
use strict;
use warnings;
use 5.020;
use autodie;
use Data::Dumper;
open my $INFILE1, '<', 'data1.txt';
open my $INFILE2, '<', 'data2.txt';
open my $OUTFILE, '>', 'common.txt';
while (!eof($INFILE1) and !eof($INFILE2)) {
my $line1 = <$INFILE1>;
my $line2 = <$INFILE2>;
my(undef, $target1) = split ' ', $line1, 2;
my(undef, $target2) = split ' ', $line2, 2;
if ($target1 eq $target2) {
print {$OUTFILE} $line1
}
}
close $INFILE1;
close $INFILE2;
close $OUTFILE;
请勿使用 bareword 文件句柄,例如文件。相反,使用my
变量:
open my $FILE, '<', 'data.txt'
从while循环中读取文件条件:
while (my $line = <$FILE>)
perl会自动对defined()
进行$line
检查,而while循环只会在没有其他行读取且<>
返回undef
时结束。
不要试图通过阅读旧的perl教程来学习perl。相反,购买最新版的“Learning Perl”(Schwartz,d Foy,Phoenix)。 Perl拥有我研究的任何编程语言的最佳书籍,因此利用该资源。对于编程书来说,“学习Perl”相当薄,所以你不需要花一年的时间来阅读它。并且,它在每章末尾都有练习,并在本书的最后给出答案。
DATA1.TXT:
a 1 2 3 4
b 5 6 7 8
c 3 4 5 5
d 2 2 2 2
data2.txt:
w 2 4 2 4
x 5 6 7 8
y 3 4 5 6
z 2 2 2 2
代码:
use strict;
use warnings;
use 5.020;
use autodie;
use Data::Dumper;
open my $INFILE1, '<', 'data1.txt';
open my $INFILE2, '<', 'data2.txt';
open my $OUTFILE, '>', 'common.txt';
LINE_FROM_FILE1:
while (my $line1 = <$INFILE1>) {
if (defined(my $line2 = <$INFILE2>)) {
my($first1, $target1) = split ' ', $line1, 2;
my($first2, $target2) = split ' ', $line2, 2;
if ($target1 eq $target2) {
print {$OUTFILE} $line1
}
}
else {
say "File2 is shorter than File1. " .
"No more lines in File2...quitting";
last;
}
}
close $INFILE1;
close $INFILE2;
close $OUTFILE;
输出:
$ rm common.txt
remove common.txt? y
$ perl 1.pl
$ cat common.txt
b 5 6 7 8
d 2 2 2 2
答案 1 :(得分:0)