• ベストアンサー

perl で複数のデータ列を結合して出力する方法

perl で、他のいくつかのプログラムが出力するデータ列を結合して出力する方法はないでしょうか? 例えば、三つのプログラム programA, programB, programC の出力が % programA 1 2 3 4 % programB 1 4 9 16 % programC 1 8 27 64 だとします。 perl スクリプトでこれらのプログラムを呼び出して、 % test.pl programA programB programC 1 1 1 2 4 8 3 9 27 4 16 64 のようにしたいのです。 よろしくお願いします。

  • Perl
  • 回答数4
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.4

最後の行をもう少しわかりやすい形にすると、次のようになります。 foreach my $index (0 .. $#out_A) { print "$out_A[$index] $out_B[$index] $out_C[$index]\n"; } .. は、範囲演算子と言います。左側の数字から右側の数字までの1刻みの リストを返します。右側の $#out_A は配列 @out_A の最後の添字ですので、 この場合 0, 1, 2, 3 のリストが得られます。 foreach では、リストの各要素が制御変数にセットされて繰り返し実行され ることになります。上のコードでは、$index が制御変数にあたります。 この制御変数は省略することができ、その場合にはデフォルト変数の $_ が代わりに使われるというわけです。

white-tiger
質問者

補足

ありがとうございます。 foreach を後ろに書くことができるということも衝撃でした。 すぐわかるPerlという本を読んだのですが(すごく良い本でしたが)、まだ知識が足らないですね。

その他の回答 (3)

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.3

バッククォートまたは qx を使用すると、プログラムの出力を Perl に取り込むことができます。 use strict; my ($programA, $programB, $programC) = @ARGV; my @out_A = qx{$programA}; chomp @out_A; my @out_B = qx{$programB}; chomp @out_B; my @out_C = qx{$programC}; chomp @out_C; print "$out_A[$_] $out_B[$_] $out_C[$_]\n" foreach 0 .. $#out_A;

white-tiger
質問者

補足

ありがとうございます。すごくエレガントですね! 最後の行だけ理解できないところがあるのですが教えていただけないでしょうか? (1) $out_A[$_]の「$_」の役割はどういったものでしょうか?($_は勉強したばかりで、下の方のような使い方ならわかるのですが、まだ知識不足のようです) (2) foreach 0 .. $#out_A; の .. の意味を教えていただけないでしょうか?(#は配列の要素数ですよね?) よろしくおねがいします。

  • rafysta
  • ベストアンサー率45% (24/53)
回答No.2

各プログラムが出力するデータ列の行数は、すべて同じですか?(今回の場合、programA, programB, programC の出力はいずれも4行になっていますが、programBだけ5行になったりということはない?)

white-tiger
質問者

補足

はい。出力行数は一緒です。

  • maura
  • ベストアンサー率46% (48/104)
回答No.1

$programA = $ARGV[0]; $programB = $ARGV[1]; $programC = $ARGV[2]; open(AOUT, "$programA |"); open(BOUT, "$programB |"); open(COUT, "$programC |"); while (<AOUT>){ my $a = $_; my $b = <BOUT>; my $c = <COUT>; print $a,$b,$c; } close(AOUT); close(BOUT); close(COUT);

white-tiger
質問者

補足

ありがとうございます。 while (<AOUT>) のところは1行ずつ読み込むんですね。 なるほど。。

関連するQ&A

  • Windows版Perlの標準入力&標準出力

    Windows2000にActive Perl5.6をインストールしています。 標準入力をそのまま標準出力するプログラムを作っているのですが うまく動きません。 DOSコマンドの使い方が間違っているのか、Perlの書き方が間違って いるのか、それともWindows版のPerlではこのような使い方はできない のか、教えてください。 ■プログラムソース(c:\test.pl) while(<>){ print; } ■実行方法 c:\data.dat|test.pl>data2.dat ■データ(data.datの中身) こんにちわ ※実行するとdata2.datにdata.datの内容がCOPYされる 予定なのですが、正しく動きません。

    • ベストアンサー
    • Perl
  • Linux上でtcpdumpの出力をperlで処理したいと考えています

    Linux上でtcpdumpの出力をperlで処理したいと考えています。 下記のようにtcpdumpの標準出力をperlの標準入力で受け取ろうとしても tcpdumpの処理が終わらないためパイプ(|)経由でperlにデータが渡ってきません。 [test.pl] $|=1; foreach(<>){ print "--- $_"; } exit; Linux上のコマンド tcpdump -l | ./test.pl これをteeに置き換えるとtcpdumpの出力はリアルタイムに表示されます。 tcpdump -l | tee a.log 質問:perlでteeを作ることはできますか?

    • ベストアンサー
    • Perl
  • awkで複数ファイルのある列を抽出し出力したい

    awkプログラミングの初心者です。 今、複数ファイル(1000ファイル)から、それぞれある列(すべて同じ列番号)のデータを抜き出して、1つのファイルに出力したいと考えています。 具体的には、1列目に共通項、2列目以降に1000ファイル分の抽出された列を、合計1001列となるような1つのファイルとして出力したいと考えております。 awkを使って出力するには、どのようなスクリプトを作ればよいか教えていただけませんでしょうか。 <イメージ> 元となるファイル(例えば下記のように3ファイル、実際には1000ファイル)があります。 file1.txt: 1  10 2  15 3  17 :  : 1000  25 file2.txt: 1  5 2  40 3  22 :  : 1000  17 file3.txt: 1  9 2  20 3  16 :  : 1000  32 出力後のファイルイメージ: 1  10  5  9 2  15  40  20 3  17  22  16 :  :  :  : 1000  25  17  32 ちなみに、自分で作成したawkスクリプト(下記)では、上記出力後のイメージとは異なり、 縦にデータが結合されてしまいました。 awk `{print $2}` ./file*.txt > Output.txt 出力後のファイル: 10 15 17 : 25 5 40 :

  • Perlの文字列削除とcsv出力の方法について

    現在、Perlを用いてtxtファイルから必要なデータだけを取り出し、それをcsv ファイルに出力したいと考えております。 Perlはほとんど触ったことがなく、色々と勉強しながら行っているのですが、期 日が迫っているという事情もあり質問させていただきます。 txtファイルには以下のような文が1000行ほどあります。 *○ △ /△/△/△/△/○.txt, ○|○): ○ ○,△:任意の数字、または文字列です。 この内、"○"のものだけを一つ一つ分けてcsvに出力したいのです。 つまり○は4つありますが、出力する際は1つ目の"○"を1行目に、2つ目の"○"を2行 目にといった形にしたいです。 そして、それが1000列分あるということになります。 上手く△のものだけを除外し、○だけを抽出する方法はあるでしょうか? どなたかよい方法をご存知のかたいらっしゃいましたら、教えていただけると幸 いです。 エクセルで行うということも考えましたが、htmlファイルが入力ファイルとなる可能性もあるためPerlで行うことにしました。

    • ベストアンサー
    • Perl
  • Perlの出力を、Perlから実行するプログラムの標準入力にしたい

    現在データを収集してくるPerlのスクリプトを作っています。 このスクリプトから、ローカルにある、別のrubyスクリプトに、収集してきたデータを渡したいのですが、rubyスクリプトは、標準入力を前提として作られています。 簡単に考えると、一旦ファイルに落として、そのファイルをリダイレクトする形でPerlからrubyスクリプトを起動すればよさそうなのはわかるんですが... なにか他にうまい方法がPerlにはあるはずだといろいろ探しているのですが、見つかりません。 ファイル渡ししか方法は無いのでしょうか?

  • perl 計算結果をファイルへ出力したい

    perl やり始めたばかりです。宜しくお願いします。 入力ファイル data.txt があるとします。 data.txt は、 123 456 789 333 555 777 以上のようなテキストファイルといたします。このファイルを 以下の様に100分の1にして出力したい。 1.23 4.56 7.89 3.33 5.55 7.77 と言うことで、この場で教えていただきました。それが、以下です。 #!/usr/bin/perl open(IN, "data.txt") or die ; @x = <IN>; close (IN); foreach $line (@x){ chomp($line); @elms = split(' ',$line); foreach $data (@elms){ print $data/100," "; } print "\n"; } おかげ様でこれはこれで上手く動きました。そこで、出力値をファイルに 書き込みたいのです。 もちろん、以下の様な方法でファイルに 書き込めるのは判っております。 計算プログラム.pl > outfile.txt しかし、上のプログラムをベースにファイルに書き込めないかと色々と 試してはみましたが、どうも上手く行きません。 どなたか教えて頂けないでしょうか? 宜しくお願い申し上げます。

    • ベストアンサー
    • Perl
  • perlで列の抜き出し

    a,b,c,d 1,2,3,4 5,6,7,8 以上のような配列のデータを読み込んだときに、 c 3 7 のように縦の列のデータを抜き出すプログラムを考えています。 これはどのように記述すればよいでしょうか。 二次元配列はperlでは不可能と言うことであまりperlでは難しいでしょうか。

  • <Perl>参照配列の出力に失敗する。

    <Perl>参照配列の出力に失敗する。 お世話になります。 配列の出力部で以下のエラーが出力されます。 Use of uninitialized value in print at test2.pl line 12. -----コーディングは以下の通りです。----- #!C:\perl use strict; use warnings; my @l = (); #----------- #GetDataへCSVファイル名と、格納用配列を渡す #----------- my $cnt = &GetData("test.csv", \@l); print "COUNT -> ".$cnt; for(my $i=0; $i < $cnt; $i++){ print $l[$i]; } ################################################################## # 概   要:指定したCSVファイルをオープンしCSVデータを配列に取得する。 # パラメータ:ファイル名, CSVデータ格納用配列 # 戻 り 値:データ取得件数 ################################################################## sub GetData { my ($f, @bf) = @_; my $rcnt = 0; print "FILE NAME -> ".$f."\n"; if ( open(FP, "<${f}") ){ print "FILE OPEN -> success.\n"; @bf = split(/,/, <FP>); close(FP); $rcnt = @bf; print "CSV GET COUNT -> ".$rcnt."\n"; } return $rcnt; } -----実行結果は以下の通りです。----- D:\>perl test.pl FILE NAME -> test.csv FILE OPEN -> success. CSV GET COUNT -> 5 Use of uninitialized value in print at test2.pl line 12. Use of uninitialized value in print at test2.pl line 12. Use of uninitialized value in print at test2.pl line 12. Use of uninitialized value in print at test2.pl line 12. COUNT -> 5 -----CSVファイルの内容は以下の通りです。(ファイル名:test.csv)----- あいうえお,かきくけこ,さしすせそ,たちつてと,なにぬねの 配列の要素数が取れているので、配列内にデータは格納されているとは思っています。 出力方法をどのように正せばよいがご教示お願い致します。

    • ベストアンサー
    • Perl
  • 3行ずつ足す

    AWK を使っていあのですが、perl への移行を目指して勉強しています。 (1) 行数が3の倍数 (2) 列数は分からない(スペース区切り。固定列数) (3) # はコメント行 というデータがあります。 このデータを perl に読み込ませて、  三行ずつ足して出力する ようなプログラムをつくっています。 例えば、6行4列のデータ test.dat # comment 1 2 3 5 3 2 1 6 2 2 2 7 4 5 6 7 6 5 4 6 5 5 5 5 を cat test.dat | sum3row.pl のように perl のプログラム sum3row.pl に読みこませて、三行ずつ足して # comment 6 6 6 18 18 18 18 18 という出力を得たいのです。 次の点で困ってます。 ●AWK の場合、今読み込んでいる行の列数は NF という変数で分かるのですが、perl ではよく分かりません。データへのアクセス自体は $data[2] のようにすれば良いことは分かっているのですが・・。 ●AWK の場合、今読み込んでいる行の番号は NR という変数で分かるのですが、perl ではよく分かりません。 すみませんが、よろしくお願いします。。 サンプルプログラムでも助かります(読んで自分で勉強しますので)。

    • ベストアンサー
    • Perl
  • Perlからsyslog経由でログを出力したい

    皆さん、こんにちは。 Perlからsyslog経由でログを出力しようと考えています。 2点質問がありますのでご存知でしたらご教授ください。 (1)Perlスクリプトからsyslog経由でログ出力する方法 いろいろ方法は考えられるかと思いますが、 よく使われるエレガントな方法をご教授していただけるとありがたいです。 通常はやはりloggerを使うのでしょうか? (2)syslog経由で任意のファイルに出力する方法 syslogで、あるプログラムからのログにおいて、 このレベルはこのファイルという分け方はできますか? できなければ別の手段はありませんか? syslog-ngであればこのようなことができるのでしょうか? もしできれば方法を教えてください。 よろしくお願いします。

    • ベストアンサー
    • Perl

専門家に質問してみよう