我有下表(带/ t分隔符的txt文件),我想编写一个脚本,以便每次将下一行的值减去前一行的值,然后获取每个值的绝对值。
43 402 51 360 66
61 63 67 66 65
63 60 69 63 58
65 53 89 55 57
103 138 135 135 85
例如:
abs(61-43)abs(63-402)abs(67-51)abs(66-360)abs(65-66)
abs(63-61)abs(60-63)abs(69-67)abs(63-66)abs(58-65)等。
这是我写的。
#!/usr/bin/perl -w
use strict;
use warnings;
my $filename = '/home/kgee/Desktop/gene_gangs/table_gangs/table_ony_numbers';
open(my $fh, '<:encoding(UTF-8)', $filename)
or die "Could not open file '$filename' $!";
$newtable=0;
$i=0;
$j=1;
while (my $row = <$fh>) {
chomp $row;
print "$row\n";
my @numbertable = split//,$filename;
for (@numbertable){
$newtable[$j]= ($i+2) -($i+1);
$temp[$i]= abs($newtable[$j]);
$newtable=$tepm[$i];
my @newtable= split//,$newtable;
print("@newtable","\n");
$i=$i+1;
}
}
我有很多错误,都是“在XXX行上,全局符号XXX需要显式的程序包名称(您是否忘记声明了“我的XXX”?)?”我在线阅读了要解决此问题的方法,您已删除了不推荐使用的使用警告;(从乞求)或在块外(而不是在内部!)声明了变量。我都尝试过,但仍然有一些警告。
my
用于在您第一次使用它时声明一个变量。
这很简单
my $newtable = 0;
您还向代码中添加了一些混淆的方法,建议您排序:
$newtable
和@newtable
-它们是不同的变量,并且很容易混淆$newtable;
和$newtable[0];
$temp
和$tepm
-这正是use warnings
可以帮助您识别的东西。 $filename
拆分为@numbertable
-我很确定这不会满足您的要求,因为它将字符串'/home/kgee/Desktop/gene_gangs/table_gangs/table_ony_numbers'
拆分为字符。您可能是指split /\t/, $row;
吗? my @newtable= split//,$newtable;
一样...我也不会按照您认为的那样做,因为$newtable
就像在程序前面实例化的那样“只是”零,并且您从不修改它。 for (@numbertable)
迭代该表中的每个元素(拆分行?),但您永远不会使用迭代器。每次迭代都将$_
设置为当前元素。但是它与$i
和$j
没有任何关系,并且您实际上似乎根本没有修改$j
-因此它保持为零。 实际上,我越看代码,恐怕就会发现它实际上并没有工作,而且您的问题要比最初的警告要深得多。
怎么样:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @previous_row;
my @new_table;
##iterate line by line - use your file handle here, <DATA> is a special case.
while ( <DATA> ) {
#strip trailing linefeed.
chomp;
#split this row on any whitespace (which includes tabs)
my @row = split;
#Handle first iteration - can't subtract 'previous row' if there isn't one.
if ( @previous_row ) {
my @new_row;
#iterate the current row
foreach my $element ( @row ) {
#grab the elements off the previous row - note "shift" modifies it, and this will
#break if you've got uneven length rows. (But you don't, and I'll leave it to you to handle that if you do.
my $previous_row_element = shift @previous_row;
#calculate new value
my $value = abs ( $element - $previous_row_element );
#stash new value into new row.
push @new_row, $value;
}
#new row is complete, so push it into the new table.
push @new_table, \@new_row;
}
#Update 'previous row' with the contents of the current row.
@previous_row = @row;
}
#lazy mode output. Iterating the array and printing values in the format you want
#is up to you.
print Dumper \@new_table;
__DATA__
43 402 51 360 66
61 63 67 66 65
63 60 69 63 58
65 53 89 55 57
103 138 135 135 85