Perl中文件减去后的绝对值

问题描述 投票:0回答:1

我有下表(带/ 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”?)?”我在线阅读了要解决此问题的方法,您已删除了不推荐使用的使用警告;(从乞求)或在块外(而不是在内部!)声明了变量。我都尝试过,但仍然有一些警告。

perl calculated-field
1个回答
0
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.