人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

CSVファイルをPerlで処理する方法について質問です。

CSVファイルに以下のようなデータが入っています。

2,4,a2,5,9,10,7,11,
5,3,4,12,2,18,2,12,
7,4,a6,11,5,2,6,4,
6,2,a9,34,4,2,7,2,
4,7,2,6,6,9,2,7,
4,9,a2,8,1,7,a1,5,
(こういう感じで続いていきます)

このファイルを読み込み,小文字aのすぐあとの数字と,aが含まれているデータの次のデータを出力させたいです。(説明が下手くそですみません)

つまり上のデータだったら,

2,5
6,11
9,34
2,8

というように出力させたいです。
データ処理のためにPerlをはじめたのですが,なかなか苦労しているのでお願いします。。。


●質問者: ishikennn
●カテゴリ:コンピュータ
✍キーワード:A1 CSV Perl くそ データ
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● thrillseeker
●20ポイント

正規表現というものを使えばうまく処理できます。

#! /usr/bin/perl

while (<>) # 引数で与えられたファイルから1行ずつ読み込んで処理する
{
 if (/a(\d+,\d+),/) { print "$1\n"; } # 正規表現に一致したら()の部分を出力する
}
◎質問者からの返答

ありがとうございます。そういうやりかたがあったんですね!

ちなみに$1というのはどういう意味なんでしょうか?


2 ● tkyk3
●20ポイント

$1は、()内にマッチした値が入っている特殊な変数です。

if ( /(\d+),(\d+),(\d+)/ ) 
 print "最初:$1、2番目:$2、3番目:$3";
}

括弧ごとにそれぞれ$1,$2,$3...と入っていきます。

プログラミングPerl〈VOLUME1〉

プログラミングPerl〈VOLUME1〉

  • 作者: ラリー ウォール ジョン オーワント トム クリスチャンセン
  • 出版社/メーカー: オライリー・ジャパン
  • メディア: 単行本

この本に紹介されています(ちょっと高いけど。でも、買って損はないです。)

あと、CSVデータの扱いに関しては「"」とかを考え出すと意外に処理が難しいので、

Perlクックブック〈VOLUME1〉

Perlクックブック〈VOLUME1〉

  • 作者: トム クリスチャンセン ネイザン トーキントン
  • 出版社/メーカー: オライリージャパン
  • メディア: 単行本

こちらも本屋さんでぱらっと見てみてください。

余談:

use Text::CSV::Simple;
my $csv = Text::CSV::Simple->new({ binary => 1 });
$csv->field_map(qw/id name address tel/);
my @list = $csv->read_file("address.txt");

これだけで、@listにCSVファイルを読み込んでしまい込む事が出来ます。毎日が発見です。頑張ってください!!

◎質問者からの返答

ちゃんとした本を買ったほうがよさそうですね。ありがとうございます。


3 ● lunlumo
●40ポイント ベストアンサー

thrillseekerさんのコードだと,aの付くデータが一行に二つ以上あった場合に最初のデータしか出力しませんね。同様に簡易な処理で行うならこんな感じになるでしょうか。

#! /usr/bin/perl

while (<>) {
print "$1\n" while ($_ =~ m/a(\d+,\d+),/g);
}

ただこの処理では少し荒いですしtkyk3の指摘されている問題もあるので,Text::CSVなりText::CSV::Simpleなりを使ってまじめに処理した方が良いでしょう。

#! /usr/bin/perl

usestrict;
useIO::File;
useText::CSV;

my$file;
my$csv;

if (scalar(@ARGV) != 1) {
print "usage: $0 DATA_FILE_PATH\r\n";
exit(0);
}

$file = new IO::File;
$file->open("<".$ARGV[0]) || die "cannot open file.";

$csv = new Text::CSV;

while (1) {
my$columns = $csv->getline($file);
last if ($csv->eof());
unless ($csv->status()) {
print STDERR $csv->error_diag()."(".$csv->error_input().")\r\n";
next;
}
for (my $i = 0; $i < scalar(@$columns) - 1; $i++) {
if ($columns->[$i] =~ m/^a(\d+)/) {
unless ($csv->combine($1,$columns->[$i+1])) {
print STDERR "invalid values\r\n";
} else {
print $csv->string()."\r\n";
}
$i++;
}
}
}

$file->close();

1;

◎質問者からの返答

Text::CSVっていうのはとても便利そうですね!ありがとうございます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ