質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

  • Perl

    464questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

  • AWK

    76questions

    AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

AWKからPerlへの変換で困っています

受付中

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 377

sheng

score 2

perlが馴染めず、awkでなんとかしていたのですが、汎用的なプログラムを作る必要があり、質問させていただきました。

data.csv

No  var1 var2 var3
1 10 A 1000
2 10 B 1000
3 10 B 2000
4 10 A 2000
5 10 A 1000

cat data.csv | awk -F ',' `{print $3}' | sort | uniq -c によって、下記の結果が得られます。
3 A
2 B

これをawkではなく、perlで列数とファイルを指定して同じような結果を得るperlプログラムを作成したいです。
perl test.pl data.csv 3

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

0

まずawk互換モードから覚えるといいでしょう。 

$ perl -F"," -ane 'print "$F[2]\n"' data.csv |sort |uniq -c

カウントを取りたいだけならuniqは必要ありませんね。 

# awk
awk -F"," '{n[$3]++}END{for(i in n){print i,n[i]}}' data.csv
# perl
perl -F"," -ane '$n{$F[2]}++; END{foreach $k (keys %n){print "$k $n{$k}\n"}}' data.csv

項目がアルファベット順に並ばないのが気持ち悪いなら 

perl -F"," -ane '$n{$F[2]}++; END{foreach $k (sort keys %n){print "$k $n{$k}\n"}}' data.csv

 perlスクリプトファイルを作る簡便な方法

コメント欄にも書きましたが、こちらに補足しておきます。
まず、perlスクリプトファイルの呼び出し方。ワンライナーで対処しているうち、より複雑なことをやりたくなって結局スクリプトファイルの作成を始めるという事態はままあることです。その場合、ワンライナー部分を単純に新規ファイルにコピーし、コマンドラインのワンライナー部分をそのファイル名に置き換え、最後にコマンドラインの-eを消すだけです。awk では逆に-fをつけなければなりませんがperlは異なります。

次に、perlのパッケージの中に標準で含まれているコンバータがあります。
awkはわかるけどperlはちょっと、という回答者氏のような方は、awkスクリプトをperlスクリプトに変換するa2pというコンバータを使えば、簡単にperlスクリプトファイルを得ることができます。同様に、sedスクリプトをperlスクリプトに変換するs2p、findコマンドと同じことをするperlスクリプトを生成するfind2perlがあります。

私は個人的にはa2pやs2pはほとんど使いませんが、find2perlはちょくちょく使います。「ディレクトリを下までたどりながら、条件に合うファイルが見つかったらそこそこ複雑な何らかの処理を行う」という作業にはとても便利です。find2perlを覚えてしまうと、findやxargsを使ったシェル芸など、まだるっこしくて覚える気にはならないくらいです。

参照: http://perldoc.jp/docs/perl/5.10.1/perlutil.pod

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/28 00:01 編集

    ご回答ありがとうございます。
    説明が不足しておりました。申し訳ございません。
    perl test.pl data.csv 3
    のように、ワンライナーではなく、perlスクリプトにて処理したいと思っております。何卒よろしくお願い致します。

    キャンセル

  • 2018/06/28 00:34

    ワンライナーで書いた部分をファイルに書きこんでperl -F "," -an test.plとするだけです。 引数を取りこみたいなら@ARGVを使って下さい。

    キャンセル

  • 2018/06/28 02:13

    a2pというツールが在ったことを忘れていた。awkスクリプトファイルを既にお持ちならこれを試してみては如何?

    キャンセル

0

Perlはあまり詳しくないですが、

perl -nle '@a=split(/,/,$_);$b{$a[2]}++;END{foreach $i(keys %b){print "$b{$i} $i"}}' data.csv

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/28 00:04

    ご回答ありがとうございます。
    説明が不足しておりました。申し訳ございません。
    perl test.pl data.csv 3
    のように、ワンライナーではなく、perlスクリプトにて処理したいと思っております。何卒よろしくお願い致します。

    キャンセル

  • 2018/07/25 20:15

    '~~’ の部分がスクリプトです。

    キャンセル

0

汎用的な、というのがどの程度を言っているのか分りませんが、

#!/usr/bin/env perl -F, -lan
use vars qw($c %h);
BEGIN{ $c = ( pop @ARGV ) -  1}
    $h{$F[$c]} ++
}{
    print "$h{$_} $_" for keys %h ;

これを保存して実行すれば、望みの形にはなります。

本格的なスクリプトを作りたいのであれば、

$ perl -MO=Deparse THIS.pl data.csv 3

で、内部解釈を文字列化して、そこからスクリプトを作成してください。

私のスクリプトが使いずらいと感じたら、先の御二方のワンライナーを同様の手段でスクリプト化して、
改造するのが良いでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

my ($file, $colnum) = @ARGV;

my %stash;

open my $fh, '<', $file
    or die "Can't open $file: $!";

while (my $line = <$fh>) {
    my @cols = split /,/, $line;
    my $var = $cols[$colnum - 1];
    $stash{$var}++;
}

close $fh
    or die "Can't close $file: $!";

my @summary = sort { $b->[1] <=> $a->[1] }
              map { [$_, ($stash{$_} || 0)] }
              keys %stash
              ;

for my $row (@summary) {
    printf "%d %s\n", reverse @{$row};
}

1;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Perl

    464questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

  • AWK

    76questions

    AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。