前回の
シェルコマンドを組み合わせる
(1)
openコマンドを組み合わせる
筆者は普段Macを使用していますが、openというコマンドがあり、
openコマンドは、
$ open foo/bar.txt$ open https://gihyo.jp/system関数を使う
では、openコマンドをPerlのコードから使うにはどうすればよいでしょうか。
Perlでシェルのコマンドを呼び出す方法はいくつかありますが、system関数を使っています。
今回のopenコマンドでは戻り値を使わないので、system関数で次のように書きます。
system 'open', 'https://gihyo.jp/';複数のWebサイトを一斉に開く
では次に、for文、if文、__のセットと組み合わせてみましょう。
my @links = <DATA>;
for (@links) {
    if ($_ =~ /(https?:\S+)/) {
    system 'open', $1;
    }
}
__DATA__
https://gihyo.jp/
https://twitter.com/
https://www.google.co.jp/このコードを実行すると、__の下に入れたURLのWebページが次々とブラウザで開かれます。
筆者は編集や執筆の仕事をする際、
複数ファイルの行数や文字数をカウントする
件の音楽全集では、
この際、
use feature 'say';
my @iter = glob "*";
my $line_sum = 0;
my $word_sum = 0;
for (@iter) {
    next if (-d "$_");
    next unless ($_ =~ /(txt|md)\z/);
    my $name = `wc -lm "$_" | awk '{ print \$NF}'`  ┓
    my $line = `wc -lm "$_" | awk '{ print \$1}'`;  |(1)
    my $word = `wc -lm "$_" | awk '{ print \$2}'`;  ┛
    chomp $name;
    chomp $line;
    chomp $word;
    $name =~ s/.*?\/?([^\/]+)\z/$1/;
    $word = $word - $line if $line > 1;
    $line++;
    print "$name =>\tlines: $line\twords: $word";
    $line_sum += $line;
    $word_sum += $word;
    say "";
}
say "";
say "Lines total:\t$line_sum";
say "Words total:\t$word_sum";コードには、wcやawkが含まれています.bashrcの関数
使い方
では、
alias lwc='perl path/to/line-word-count.pl'前述の分割したファイルを収めたディレクトリでツールを実行すると、
$ lwc
01_beginning.txt => lines: 74 words: 6943
02_Franz-Schubert.txt =>    lines: 130 words: 3989
03_Robert-Schumann.txt =>   lines: 124 words: 5231
04_Frederic-Chopin.txt =>   lines: 110 words: 4741
05_Franz-Liszt.txt =>   lines: 59 words: 1774
06_Richard-Wagner.txt =>    lines: 186 words: 8028
07_Johannes-Brahms.txt =>   lines: 79 words: 1922
08_Gabriel-Faure.txt => lines: 111 words: 3382
09_Gustav-Mahler.txt => lines: 54 words: 1976
10_Richard-Strauss.txt =>   lines: 107 words: 2689
11_Pyotr-Tchaikovsky.txt => lines: 77 words: 3509
12_Jean-Sibelius.txt => lines: 61 words: 2011
13_conclusion.txt =>    lines: 228 words: 9214
Lines total: 1400
Words total: 55409こうした長丁場の仕事では、
ほかのツールを組み合わせる
ここまでに、
ターミナル操作を楽にする
俗に
しかし、cdコマンドを打つのは面倒ですし、
$ ls -1
2018-12-31-10-25-14.md
2019-01-02-00-33-37.md
2019-01-02-01-12-25.md
2019-01-03-03-48-32.md
2019-02-15-11-21-47.mdこのような問題に悩んでいるときに、pecoや、choといったコマンドラインツールの存在を知りました。pecoは標準入力から渡された行をインクリメンタルに絞り込み、choはそのシンプルさをさらに追求し、chocoです。
.bashrcの設定
chocoを使うためには、.bashrcの設定をしておく必要があります。
function choco {                       ┓
    local path=$(perl "$@")            |
    local basename=${path##*/}         |
    local dirname                      |
                                       |
    if [ -f "$path" ]; then            |(1)
        dirname="${path%%$basename}"   |
    elif [ -d "$path" ]; then          |
        dirname="$path"                |
    fi                                 |
    cd "$dirname"                      |
}                                      ┛
alias j='choco path/to/choco.pl -c open'    ――(2)
alias ja='choco path/to/choco.pl -c open -a'  ――(3)まず、
使い方
では、carvoのリポジトリを例に用います。ルートディレクトリでコードを実行すると、pecoの選択画面に切り替わり、
QUERY>  ――(1)
exit  ――(2)
../  ――(3)
docs/
lib/
local/
src/
t/
Build.PL
ChangeLog.md
(省略)QUERY欄openコマンドを指定しておくと、../exit
前述のとおり、pecoが使われていますが、choを指定することもできます。エイリアスで設定する場合は、
alias jc='choco path/to/choco.pl -c open -s cho'chocoは今や筆者にとってなくてはならない存在ですが、while文やif文など、
特定の文字列を含むファイルを検索する
chocoの応用として、find-word.というツールも作りました。
これはカレントディレクトリ配下を対象に、
編集の仕事をしていると、
しかしこのツールを使えば、
使い方
対象となるプロジェクトのルートディレクトリでコードを実行します。この際、openコマンドでファイルを開くようにオプションを指定し、fwというエイリアスに設定して呼び出しています。
alias fw='perl path/to/find-word.pl -c open'たとえば、fw yamlと打ち込めば、yamlという文字列を含むファイル名とその行の情報が一覧表示されます。
$ fw yaml
QUERY>
cpanfile:1:requires 'YAML::Tiny';
lib/Carvo.pm:15:use YAML::Tiny;
lib/Carvo.pm:18:    my $yaml = YAML::Tiny->read('config.ya
ml');
lib/Carvo.pm:19:    my $attr = $yaml->[0];
lib/Set/Generator.pm:8:use YAML::Tiny;
(省略)この一覧画面はpecoで表示しているので、openコマンドによって開かれます。
このツールでは日本語の検索もできるので、
ゲーム感覚で英単語を学習する
これまでに紹介したツールは、
Perlの入門初期にwhile文や標準入出力の方法を教わると、
say '数字を入力してください。
1: グー, 2: チョキ, 3: パー';
my %janken = (
    1 => 'グー', 2 => 'チョキ', 3 => 'パー',
);
while (1) {
    print '> ';
    my $input = <STDIN>;
    chomp $input;
    next if $input !~ /[123]/;
    my $output = int(rand(3));
    $output++;
    say "あなた: $janken{$input}";
    say "わたし: $janken{$output}";
    my $result = $input - $output;
    if ($input == $output) {
        say "あいこ";
    }
    elsif ($result == 2 || $result == -1) {
        say "あなたの勝ち";
    }
    elsif ($result > 0 || $result == -2) {
        say "あなたの負け";
    }
}$ perl janken.pl
数字を入力してください。
1: グー, 2: チョキ, 3: パー,
> 2
あなた: チョキ
わたし: パー
あなたの勝ち
> 1
あなた: グー
わたし: グー
あいこ
> (省略)シンプルなコードですが、carvoです。
使い方
ターミナルでコードを実行すると、pecoのUI
QUERY>
sample1
sample2
sample3
exitここで好きなコースを選択すると、
Welcome to the "sample1"
You can choose a number from 1-31
play   ――(1)
again
card
exit   ――(2)
list
fail
voice
helpこの画面から、choが使われています。play
expect
- ~を推測する
- ~を提案する
- (~に)頼る
- ~の特徴を述べる
- ~を予期する
- [Give up!]選択が正解ならポイントが加算され、exit
小さなコードの積み上げ方
carvoはじゃんけんゲームと同様、while文を中心とする単純な構造のプログラムなので、
コードの量が多くなれば、
my @arr = qw(apple orange lemon);        ┓
say scalar @arr;                         |(1)
say $#arr;                               ┛
__END__   ――(2)
my $foo = "abc";            ┓
$foo =~ s/a(?=b)/x/;        |
say $foo;                   |(3)
$foo =~ s/(?<=b)c/x/;       |
say $foo;                   ┛
__END__
my @foo = qw(apple lemon);   ┓
my @bar = (@foo, @foo);      |(4)
say for @bar;                ┛
__END__
(省略)このファイルで扱う内容はさまざまです。配列の要素数を知るにはどうすればよいのか__
__はその下にあるコードを一括でコメントアウトしてくれるトークンです
こうして事前に挙動を確認してから本番のコードに手を入れるようにすると、pと打てばこのファイルが立ち上がるようにエイリアスを設定しています。
alias p='open path/to/sandbox.pl'<続きの
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
 イミュータブルデータモデルで始める
 実践データモデリング
 業務の複雑さをシンプルに表現!
- 特集2
 いまはじめるFlutter
 iOS/Android両対応アプリを開発してみよう 
- 特集3
 作って学ぶWeb3
 ブロックチェーン、スマートコントラクト、 NFT 


