古い記事
ランダムジャンプ
新しい記事
自分用プログラミングメモです。

実験用のPerlスクリプトを作るときに、使うフィールド(カラム)を指定する機能を入れたりするが、その部分だけ取り出して雛形化。コマンドラインオプションとの組み合わせ。

テストファイル


適当。TSV。
colsel-test.txt
身長	性別	自宅	あれ	これ	それ
176	1	0	1	0	1
170	0	0	0	1	1
164	0	1	1	1	0

cut式フィールド指定


フィールドをカンマ区切りの数字リストで指定する。"1" や "1,2" や "1,3,5,6" など。

"man cut" より:
-f list
        The list specifies fields, separated in the input by the field
        delimiter character (see the -d option.)  Output fields are sepa-
        rated by a single occurrence of the field delimiter character.

■サンプルコード(colsel-f.pl):
#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;

my $fields = "";
GetOptions(
    "fields=s" => \$fields, # select only these fields (origin 1)
    );
my @flds = map {$_ - 1} split(/,/, $fields);

while (<>) {
    chomp;
    my @cols = $fields ? (split/\t/)[@flds] : split/\t/;
    ### do something
    print "@cols\n";
}

■実行例:
% ./colsel-f.pl colsel-test.txt
身長 性別 自宅 あれ これ それ
176 1 0 1 0 1
170 0 0 0 1 1
164 0 1 1 1 0
% ./colsel-f.pl -f 1 colsel-test.txt
身長
176
170
164
% ./colsel-f.pl -f 6 colsel-test.txt
それ
1
1
0
% ./colsel-f.pl -f 1,3,5 colsel-test.txt
身長 自宅 これ
176 0 0
170 0 1
164 1 1

sort式フィールド指定


カンマ区切りの数字リスト(1つか2つ)でフィールド範囲を指定する。"1" や "2" だと1つ。"1,3" だと 1 から 3 までのフィールド(3つ)。"2,6" だと 2 から 6 までのフィールド(5つ)。

"man sort" より:
-k, --key=POS1[,POS2]
       start a key at POS1, end it at POS2 (origin 1)

■サンプルコード(colsel-k.pl):
#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;

my $key_at = "";
GetOptions(
    "key=s" => \$key_at, # start a key at POS1, end it at POS2 (origin 1)
    );
my ($pos1, $pos2) = map {$_ - 1} split(/,/, $key_at, 2);

while (<>) {
    chomp;
    my @cols = $key_at ? (split/\t/)[$pos1..($pos2||$pos1)] : split/\t/;
    ### do something
    print "@cols\n";
}

■実行例:
% ./colsel-k.pl colsel-test.txt
身長 性別 自宅 あれ これ それ
176 1 0 1 0 1
170 0 0 0 1 1
164 0 1 1 1 0
% ./colsel-k.pl -k 1 colsel-test.txt
身長
176
170
164
% ./colsel-k.pl -k 4 colsel-test.txt
あれ
1
0
1
% ./colsel-k.pl -k 1,3 colsel-test.txt
身長 性別 自宅
176 1 0
170 0 0
164 0 1
% ./colsel-k.pl -k 2,6 colsel-test.txt
性別 自宅 あれ これ それ
1 0 1 0 1
0 0 0 1 1
0 1 1 1 0

議論


cut で必要なフィールドだけ取り出すことを前提に(パイプで受ける)プログラムを作ればいいじゃん、という意見もあり。まったくもってその通りで、それで済むようなタスクはそれで良いかと。
この記事に言及しているこのブログ内の記事