我希望循环遍历文件中的多个文件及其各自的行。我已经成功完成了。我现在想要做的是根据其中一列中的数值删除文件中的行。
如果我有这样的输入:
XP.sta1 -41.5166 0.0513 0.6842 0.1794 0 CPHI.BHZ 300.2458 -42.2436
XP.sta2 3.5972 0.0500 0.7699 0.1213 0 E000.BHZ 300.5616 2.5545
XP.sta3 3.7112 0.0267 0.7813 0.1457 0 E002.BHZ 300.6140 2.6160
XP.sta4 4.2891 0.0214 0.6870 0.1308 0 E004.BHZ 301.2073 2.6006
其中第九列是我想看的列。我需要在第9列中移除该值(让我们为其分配一个变量$ time),如果该$ time是> 10或小于-10,删除整行。到目前为止,我已经尝试过这个:
unless (($time < -10) || ($time > 10) {
print OUT2 ($stlat," ",$stlon," ",$eqlat," ",$eqlong," ",$eqdepth," ",$time,"\n");
}}
但是我得到以下输出:
XP.sta1 -41.5166 0.0513 0.6842 0.1794 0 CPHI.BHZ 300.2458 2.5545
XP.sta2 3.5972 0.0500 0.7699 0.1213 0 E000.BHZ 300.5616 2.6160
XP.sta3 3.7112 0.0267 0.7813 0.1457 0 E002.BHZ 300.6140 2.6006
XP.sta4 4.2891 0.0214 0.6870 0.1308 0 E004.BHZ 301.2073
正如您所看到的,整条线路都没有删除 - 只有符合真实值的值才会被删除,除非&#39;条件,然后其他值在第9列中向上移动。如何删除整行,而不仅仅删除第九列?
我希望在哪里编辑我的脚本:
open(TABLEC,$File);
@tablec = <TABLEC>;
for ($j = 2; $j < $stop; $j++) {
chomp ($tablec[$j]);
($netSta,$delayTime) = (split /\s+/,$tablec[$j])[1,9] ;
}
在这个for循环中,我循环遍历每个文件,读取从2到&#39;停止&#39;的行,并切断返回字符。我将第9列设置为延迟时间变量。所以我循环遍历每一行,但我还不想打印任何东西(稍后会在我的脚本中)。我只想删除整行,以便稍后在我的脚本中打印行时,第9列值为&gt; abs(10)的行不存在。
答案 0 :(得分:1)
我只是跳过这一行:
use warnings;
use strict;
while(<DATA>){
my @split = split;
next if $split[8] > 10 or $split[8] < -10;
print "$_\n";
}
XP.sta2 3.5972 0.0500 0.7699 0.1213 0 E000.BHZ 300.5616 2.5545
XP.sta3 3.7112 0.0267 0.7813 0.1457 0 E002.BHZ 300.6140 2.6160
XP.sta4 4.2891 0.0214 0.6870 0.1308 0 E004.BHZ 301.2073 2.6006
答案 1 :(得分:0)
您还没有足够的代码来诊断问题,但您提出的问题很简单就是这样做了
use strict;
use warnings;
while ( <DATA> ) {
print unless abs((split)[8]) > 10;
}
__DATA__
XP.sta1 -41.5166 0.0513 0.6842 0.1794 0 CPHI.BHZ 300.2458 -42.2436
XP.sta2 3.5972 0.0500 0.7699 0.1213 0 E000.BHZ 300.5616 2.5545
XP.sta3 3.7112 0.0267 0.7813 0.1457 0 E002.BHZ 300.6140 2.6160
XP.sta4 4.2891 0.0214 0.6870 0.1308 0 E004.BHZ 301.2073 2.6006
<强>输出强>
XP.sta2 3.5972 0.0500 0.7699 0.1213 0 E000.BHZ 300.5616 2.5545
XP.sta3 3.7112 0.0267 0.7813 0.1457 0 E002.BHZ 300.6140 2.6160
XP.sta4 4.2891 0.0214 0.6870 0.1308 0 E004.BHZ 301.2073 2.6006
答案 2 :(得分:0)
我认为您的问题已得到解答,请在此处添加一些可以帮助您完成编辑内容的内容
代码上的一些要点
词汇变量的标识符应仅包含小写字母,小数位和下划线。大写字母保留用于全局变量,例如常量和包名称
您应该使用词法文件句柄以三参数形式open
您应该始终验证open
是否成功。如果失败,您的程序应该die
并在die字符串中包含$!
的值,以显示为什么操作失败
这些点一起意味着
open(TABLEC, $File);
变为
open my $tablec_fh, '<', $File or die qq{Unable to open "$File" for input: $!};
您可以chomp
chomp @tablec
整个数组
你应该避免使用C风格的for
循环,因为它很少是一个不错的选择。 Perl允许你迭代一个范围,你应该利用它。所以
for ($j = 2; $j < $stop; $j++) { ... }
变为
for my $j ( 2 .. $stop-1 ) { ... }
split /\s+/
几乎应始终为split ' '
。后者是操作符的特殊情况,如果参数字符串具有前导空格,则阻止它返回初始空字段。如果您在没有任何参数的情况下致电split
,则默认为split ' ', $_
这里重写了您考虑这些要点的示例代码。我希望它比我以前的答案更合适
open my $tablec_fh, '<', $File or die qq{Unable to open "$File" for input: $!};
my @tablec = <$tablec_fh>;
chomp @tablec;
close $tablec_fh;
for my $i ( 2 .. $stop-1 ) {
my $row = $tablec[$i];
my ($net_sta, $delay_time) = (split ' ', $row)[0,8];
next unless abs($delay_time) <= 10;
# Do stuff with $row
}