2011-08-17 71 views
0

我在Perl的真正的新,並已試圖拼湊出一個解決方案。當我運行這個程序時,我沒有收到任何錯誤,也沒有顯示任何內容。如何使用Perl從製表符分隔的文件中提取特定列?

的代碼如下:

#!/usr/bin/perl 
open (DATA, "<test1.txt") or die ("Unable to open file"); 
use strict; use warnings; 
my $search_string = "Ball"; 
while (my $row = <DATA>) { 

    last unless $row =~ /\S/; 
    chomp $row; 
    my @cells = split /\t/, $row; 

    if ($cells[0] =~/$search_string/){ 
     print $cells[0]; 
    } 
} 

我的測試數據文件看起來像這樣

Camera Make  Camera Model Text Ball Swing 
a  b  c  d  e 
f  g  h  i  j 
k  l  m  n  o 

我想看看它是如何工作之前,我使用的實際測試數據文件..

那麼我該如何搜索說「球」並讓它返回「din」

+1

你不是要求幫助Perl。你要爲你寫一份作業,因爲你上面的代碼與你最後一行所要求的無關。請寫一個你正在試圖用Perl實現的算法,然後問你爲什麼Perl的實現不起作用 - 目前,你的問題的答案是「你的代碼與你的任務是無關的」 – DVK

+0

我保證這個是不是任務...但無論如何...這怎麼不適用..我正在定義我正在尋找的東西,並通過/ \ t /分裂文本,這是我相信的標籤,並將其存儲在一個數組中..我在問什麼是「我如何搜索該數組並獲取相關列? –

+1

請參閱我的答案中的提示。您正在解析文件;您只是沒有使用解決問題的邏輯/算法。暗示應該足以讓你的球滾動(沒有雙關語意思) – DVK

回答

0

試試這個:

#!/usr/bin/perl 
use strict; 
use warnings; 

open (DATA, "<test1.txt") or die ("Unable to open file"); 
my $search_string = "Ball"; 

my $header = <DATA>; 
my @header_titles = split /\t/, $header; 
my $extract_col = 0; 

for my $header_line (@header_titles) { 
    last if $header_line =~ m/$search_string/; 
    $extract_col++; 
} 

print "Extracting column $extract_col\n"; 

while (my $row = <DATA>) { 
    last unless $row =~ /\S/; 
    chomp $row; 
    my @cells = split /\t/, $row; 
    print "$cells[$extract_col] "; 
} 
+0

這個作品......但我不明白你是如何做它做的...當你說'我的$ header = '將文件放入$ header,然後放入@header標題通過選項卡點亮頭文件,但不會將列名放在行而不是列中? –

+0

@David:這不是<>的工作原理。在標量上下文中,它從文件中讀取一行。 [請閱讀perlop手冊的I/O操作員部分](http://perldoc.perl.org/perlop.html)。 –

+1

如果你使用**三個參數[open](http://perldoc.perl.org/functions/open.html) –

2

r eason你沒有得到任何錯誤是因爲你的程序完全按照你的要求(打印包含字符串「Ball」的所有第一列值)。由於第一列中沒有任何單元格包含該字符串,因此您的程序不會打印任何內容。

你的問題不在於你的Perl(它可以使用一些小的改進風格 - 特別是你使用的open()過時的形式 - 但大多是罰款),它是有你的算法

提示:在算法中你的首要任務應該是尋找哪一列(按編號)是「球」專欄。

0

您可以使用Text::CSV_XS很方便地提取數據爲您服務。對於您的有限數據可能是過度的,但它是一個非常穩固的解決方案。

這裏我只是用DATA標籤所包含的數據,但如果你願意,你可以替換成一個文件句柄,如open my $fh, '<', 'text1.txt';和改變*DATA$fh

輸出:

d i n 

代碼:

use warnings; 
use strict; 
use Text::CSV_XS; 
use autodie; 

my $csv = Text::CSV_XS->new({ sep_char => "\t" }); 
my @list; 
$csv->column_names ($csv->getline (*DATA)); 
while (my $hr = $csv->getline_hr(*DATA)) { 
    push @list, $hr->{'Ball'}; 
} 

print "@list\n"; 
__DATA__ 
Camera Make Camera Model Text Ball Swing 
a b c d e 
f g h i j 
k l m n o 

埃塔:如果你打算削減&粘貼嘗試一下,確保標籤結轉在數據中。

2

嘗試了這一點:

use strict; 
use warnings; 
use Data::Dumper; 
use List::MoreUtils qw<first_index>; 

my $column = first_index { $_ eq 'Ball' } split /\t/, <DATA>; 
say Data::Dumper->Dump([ $column ], [ '*column' ]); 
my @balls = map { [split /\t/]->[$column] } <DATA>; 
say Data::Dumper->Dump([ \@balls ], [ '*balls' ]); 
__DATA__ 
Camera Make Camera Model Text Ball Swing 
a b c d e 
f g h i j 
k l m n o 

你會幾乎要把手從DATA更改爲某個文件,你open -ed。

open(my $in, '<', '/path/to/data.file') 
    or die "Could not open file: $!" 
    ; 

然後替換爲<DATA><$in>

+0

+1很酷的解決方案;) – TLP

相關問題