前回の
シェルコマンドを組み合わせる
(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