,我寫需要做到這一點的程序:最佳方式是在Perl定義(0和「」的定義)
- 讀取文件的每一行
- 如果行包含一個有序對(x,y)的存儲有序對
- 所述下一個有序對之前,將會有一個行的文件的,與「結果」處的,所述端
- 存儲中的有序對開始行作爲「值」和「錯誤」
- 打印出對應X,Y,值,誤差以CSV格式
- 讀下一個(X,Y)的值等,在(X,Y)線和(值,誤差)線將替代文件
這不是一項家庭作業。正如你所看到的,我已經有了17行代碼。我想知道是否可以使用更少的行或更簡潔的代碼完成此任務,同時至少保持此版本具有的可讀性級別,並且保持Perl樣式(例如包含和第一個可執行行之間的換行符)。
,我有至少激動的線是
if (defined($x) && defined($y) && defined($val) && defined($err))
有沒有更好的方式做一個斷言照顧交替數據的文件嗎?如果我不使用defined()函數,那麼程序不會按預期運行,因爲某些x和y座標是0值。
#!/usr/bin/perl
use strict;
print "X,Y,Val\n";
foreach (@ARGV){
open log,$_ or die $!;
my ($x,$y,$val,$err);
while(<log>){
chomp;
($x,$y) = ($1,$2) if (/\((\d*|-\d*),(\d*|-\d*)\)/);
($val,$err) = ($1,$2) if (/^Results.*\((.*),(.*)\)$/);
if (defined($x) && defined($y) && defined($val) && defined($err)){
print "$x,$y,$val:$err\n";
($x,$y,$val,$err) = undef;
}
}
}
謝謝大家的答案,我正在學習很多新的Perl語法。 我已經想出瞭如何將這個腳本降至10行。我在自己寫這篇文章的行數上挑戰自己。
#!/usr/bin/perl
use strict;
print "X,Y,Val\n";
open LOG,"<@ARGV[0]" or die $!;
while(<LOG>){
chomp;
print "$1,$2," if (/\((\d*|-\d*),(\d*|-\d*)\)/);
print "$1:$2\n" if (/^Results.*\((.*),(.*)\)$/);
}
另一個更新。使用答案中的信息,我能夠將其降至8行。我還改進了正則表達式,並確保只有在提供多個文件時纔會打印標題。
#!/usr/bin/perl
use strict;
while(<>){
print "X,Y,Val\n" if ($. == 1);
print "$1,$2," if (/.*\((-?\d+),(-?\d+)\)/);
print "$1:$2\n" if (/^Results.*\((.*)\).*\((.*)\)$/);
}
聽起來像您可以將輸入記錄分隔符設置爲'結果',然後搜索每個記錄的x,y值。 – DavidO
@DavidO很遺憾,如果「結果」是正則表達式篩選出的行之一中的有效字符串,那麼這將不起作用。如果文件很大並且座標線和結果線之間有很長的距離,它也可能導致內存問題。 –
如果你提到的標準是可能性,那麼這是行不通的,絕對可能是這種情況......也可能不是。 ;)除非我們看到我們無法確定的數據樣本。無論如何,如果不是這個練習,這是一般性的考慮;我們通常會過分關注換行符分隔的記錄,當通過新鮮眼光查看數據集時可能會發現更方便的記錄分隔符,以方便更簡單的數據刪除。 – DavidO