首页 > 解决方案 > perl中减法后文件的绝对值

问题描述

我有下表(带有 /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

例如:

绝对(61-43) 绝对(63-402) 绝对(67-51) 绝对(66-360) 绝对(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”?)?” 我在网上读到,为了解决这个问题,你已经删除了使用警告;(从乞求中)这是不推荐的,或者在块外(而不是在块内!)声明变量。我都尝试了,但仍然有一些警告。

标签: perlcalculated-field

解决方案


首先确定:永远不要“关闭警告”。你会关掉你车上的警告,并期望它结束吗?存在警告是因为您需要修复某些问题,而不是忽略。

my用于在您第一次使用它时声明一个变量。

这很简单

my $newtable = 0;

您还在代码中添加了一些混淆路线,我建议您进行排序:

  • 正确缩进
  • 不要使用$newtableand - 它们是不同的变量,而且@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但它与and没有任何关系$j,而且您实际上似乎根本没有修改$j- 所以它保持为零。
  • perl -w并且use warnings;是多余的。您可能应该坚持使用其中一种。use warnings;(我个人赞成use strict;)。

实际上,我越是查看代码,恐怕就会发现它实际上不起作用,而且您的问题比您最初的警告更深入一些。

怎么样:

#!/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

推荐阅读