文件:
1,2015-08-20,00:00:00,89,1007.48,295.551,296.66,
2,2015-08-20,03:00:00,85,1006.49,295.947,296.99,
3,2015-08-20,06:00:00,86,1006.05,295.05,296.02,
4,2015-08-20,09:00:00,85,1005.87,296.026,296.93,
5,2015-08-20,12:00:00,77,1004.96,298.034,298.87
代码:
use IPC::System::Simple qw( capture capturex );
use POSIX;
my $tb1_file = '/var/egridmanage_pl/daily_pl/egrid-csv/test.csv';
open my $fh1, '<', $tb1_file or die qq{Unable to open "$tb1_file" for input: $!};
my @t1_temp_12 = map {
chomp;
my @t1_ft_12 = split /,/;
sprintf "%.0f", $t1_ft_12[6] if $t1_ft_12[2] eq '12:00:00';
} <$fh1>;
print "TEMP @t1_temp_12\n";
my $result = @t1_temp_12 - 273.14;
print "$result should equal something closer to 24 ";
$result
值打印出-265.14
,让我觉得@t1_temp_12
已经散列
所以我试着做awk
my $12temp = capture("awk -F"," '$3 == "12:00:00" {print $7 - 273-.15}' test.csv");
我尝试使用``,qx,open,系统使用awk命令都具有相同的错误结果
但这错误了。在命令行执行awk时,我得到了有利的结果。
答案 0 :(得分:4)
这看起来像这里有一些货物崇拜节目。 看起来就像你想要做的就是找到12:00:00
的行并以C度而不是K来打印温度。
可以这样做:
#!/usr/bin/perl
use strict;
use warnings;
while (<DATA>) {
my @fields = split /,/;
print $fields[6] - 273.15 if $fields[2] eq "12:00:00";
}
__DATA__
1,2015-08-20,00:00:00,89,1007.48,295.551,296.66,
2,2015-08-20,03:00:00,85,1006.49,295.947,296.99,
3,2015-08-20,06:00:00,86,1006.05,295.05,296.02,
4,2015-08-20,09:00:00,85,1005.87,296.026,296.93,
5,2015-08-20,12:00:00,77,1004.96,298.034,298.87
打印:
25.72
您实际上不需要执行map
sprintf
等。(如果您确实希望对其进行格式化,可以对该输出执行printf
)。
编辑:从评论中,似乎混淆的一个原因是从数组中提取元素。一个数组是零个或多个标量元素 - 你不能只将一个元素分配给另一个,因为......好吧,如果不只有一个元素会发生什么(这是通常的情况)。
给定一个数组,我们可以:
pop @array
将返回最后一个元素(并将其从数组中删除),以便您my $result = pop @array;
[0]
是数组的第一个元素,因此我们可以my $result = $array[0];
my ( $result ) = @array;
- 因为在左侧我们现在有一个数组,它是一个单独的元素 - @array
的第一个元素进入{{1 }}。 (其余部分未在此方案中使用 - 但您可以执行$result
所以在你的例子中 - 如果你要做的是检索符合条件的值 - 作业的常规工具是my ( $result, @anything_else ) = @array;
- 它通过对每个元素应用条件测试来过滤数组。
所以:
grep
我们可以减少到:
my @lines = grep { (split /,/)[2] eq "12:00:00" } <DATA>;
print "@lines";
print $lines[0];
但是因为我们想要转换我们的数组 - my ( $firstresult ) = grep { (split /,/)[2] eq "12:00:00" } <DATA>;
print $firstresult;
是工作的工具。
map
首先我们:
但就个人而言,我认为这有点复杂,可能很难理解 - 而是建议:
my ( $result ) = map { (split /,/)[6] - 273.15 } grep { (split /,/)[2] eq "12:00:00" } <DATA>;
print $result;
迭代您的数据,拆分 - 并测试 - 每一行,当您找到符合条件的行时,设置my $result;
while (<DATA>) {
my @fields = split /,/;
if ( $fields[2] eq "12:00:00" ) {
$result = $fields[6] - 273.15;
last;
}
}
print $result;
并保释出循环。
答案 1 :(得分:3)
@t1_temp_12
是一个数组。你为什么要从中减去一个值?
my $result = "@t1_temp_12 - 273.14";
您想要这样做吗?
@t1_temp_12 = map {$_ - 273.14} @t1_temp_12;
作为shell one-liner,您可以将整个脚本编写为:
perl -F, -lanE 'say $F[6]-273.14 if $F[2] eq "12:00:00"' <<DATA
1,2015-08-20,00:00:00,89,1007.48,295.551,296.66,
2,2015-08-20,03:00:00,85,1006.49,295.947,296.99,
3,2015-08-20,06:00:00,86,1006.05,295.05,296.02,
4,2015-08-20,09:00:00,85,1005.87,296.026,296.93,
5,2015-08-20,12:00:00,77,1004.96,298.034,298.87
DATA
25.73