2016-03-29 4 views
0

列の最初の項目である特定の単語「ELECTRICIANS」を探したい.csvファイルがあります。私はELECTRICIANSという名前で列全体を印刷したいので、他の単語をgrepするとエラーが出力されるはずです。grepコマンドを使用して単語を検索し、perlスクリプトで列全体を表示します。

次のように私はgrepの操作を行っています

my $exit = system("grep -q $column_name $file_name"); 
if ($exit == 0) 
{ 
     print "Entered column name $column_name found in file $file_name\n"; 
} 
else { 
     print "Column name not found, try again!\n"; 
     exit; 
} 

を今、私は「電気技師」の下で、ファイル内の列を印刷する方法を教えてください。次のように.csvファイルの

内容は次のとおりです。

WEEK,SITE ENGINEERS,SITE ENGINEERS 2,ELECTRICIANS,ELECTRICIANS 2 
ONE,13,28,17,29 
TWO,13,30,18,27 
THREE,13,30,14,23 
FOUR,15,30,12,29 
FIVE,15,22,16,24 
SIX,16,30,20,30 
SEVEN,12,27,13,29 
EIGHT,19,22,16,29 
NINE,19,21,19,30 
TEN,12,22,14,30,13 
+0

をあなたのアプローチでは、Perlの変数にあなたのgrepコマンドの結果を格納する必要があります。これは、 'system(" grep ... ")'を使うことはできませんが、 'qx(grep ....)'のようなものを使うことを意味します。しかし、なぜあなたはその行をグレープするためだけに子プロセスを作成しますか?これをPerl内で簡単に行うことができます。 – user1934428

+0

私はqx構文を認識していません。 grepコマンドの出力を変数に保存するにはどうすればよいですか? –

+0

'my $ output = qx(...)'です。 [perlop](http://perldoc.perl.org/perlop.html#Quote-Like-Operators)のマンページを参照してください。 – user1934428

答えて

0

あなたはPerlスクリプトを書いているし、いくつかの他のシェル関数を呼び出すためにシェルに出た子プロセスを生成する必要はありません。 Perlにはgrepが組み込まれています。Perlで同じ結果をどのように達成できるかを示す例として以下のものがあります。スクリプトを説明するためのコメントも追加しました。

use strict; 
use warnings; 

#set the column name, this could be changed to accept input from user, 
#also read from the data file handle, this could also be changed to read from any other file 
my $column = "ELECTRICIANS"; 
my @headers = split(',',<DATA>); 

#Check for the column name rom the headers just read from the file handle, if not found then exit 
unless (grep {$_ eq "$column"} @headers){ 
    print "Column name $column not found, try again!\n"; 
    exit 1; 
} 

print $column, "\n"; 

#if we got to hear then the CSV file must have the column we are insterested in so start looping though the lines 
#split each line into fields then for each lin make a hash using the headers and the fields. then we can print the column 
#we are interested in 
while(<DATA>){ 
    chomp(); 
    my @fields = split(','); 
    my %data; 
    @data{@headers}[email protected]; 
    print $data{$column}, "\n"; 
} 

__DATA__ 
WEEK,SITE ENGINEERS,SITE ENGINEERS 2,ELECTRICIANS,ELECTRICIANS 2 
ONE,13,28,17,29 
TWO,13,30,18,27 
THREE,13,30,14,23 
FOUR,15,30,12,29 
FIVE,15,22,16,24 
SIX,16,30,20,30 
SEVEN,12,27,13,29 
EIGHT,19,22,16,29 
NINE,19,21,19,30 
TEN,12,22,14,30,13 

これは、各ラインの読み取りおよびハッシュに入れているとして、あなたは、各フィールドの列の名前を知っているように、あなたはまた、他の列を印刷することができ、出力

ELECTRICIANS 
17 
18 
14 
12 
16 
20 
13 
16 
19 
14 

を生成します。

1

サンプルデータの最後の行に余分な列があるようです。

しかし、これはあなたがしたいことです。

#!/usr/bin/perl 

use strict; 
use warnings; 
use 5.010; 

# read header 
my @cols = split /,/, <DATA>; 

# Process the rest of the data 
while (<DATA>) { 
    my %data; 
    @data{@cols} = split /,/; 
    say $data{ELECTRICIANS}; 
} 

__DATA__ 
WEEK,SITE ENGINEERS,SITE ENGINEERS 2,ELECTRICIANS,ELECTRICIANS 2 
ONE,13,28,17,29 
TWO,13,30,18,27 
THREE,13,30,14,23 
FOUR,15,30,12,29 
FIVE,15,22,16,24 
SIX,16,30,20,30 
SEVEN,12,27,13,29 
EIGHT,19,22,16,29 
NINE,19,21,19,30 
TEN,12,22,14,30,13 
0

私はしばしば私のワンライナーと批判を受けるが、ここでは一つだ:

perl -F, -slane ' 
    if ($. == 1) { 
     for ($i=0; $i<@F; $i++) { 
      if ($F[$i] eq $colname) { 
       $colno = $i; 
       last; 
      } 
     } 
     die "cannot find $colname column" unless defined $colno; 
    } 
    print $F[$colno] 
' -- -colname=ELECTRICIANS file.csv 
関連する問題