Perl Hackers Hub

第57回 自作ツールによる日常業務効率化―初歩的なコードだけで身近な問題を解決!(2)

この記事を読むのに必要な時間:およそ 5.5 分

ほかのツールを組み合わせる

ここまでに,Perlの初歩的な構文で作ったツール,シェルコマンドを組み合わせたツールを紹介しました。次に紹介するのは,ほかのプログラマーが開発,公開したツールを組み合わせた例です。

ターミナル操作を楽にする

俗に「黒い画面」と呼ばれるターミナルは,非エンジニアにとって怖い対象とされがちですが,筆者はファイルの検索や操作を行う際もキーボードから手を離さずに済むという理由で,MacではFinderよりもターミナルをよく使います。

しかし,ターミナル操作でも不便な場面は少なくありません。たとえば,ディレクトリを移動するたびに毎回cdコマンドを打つのは面倒ですし,ディレクトリ内に似た名前のファイルが複数ある場合には[Tab]キーでの補完が効きづらく,次のようなファイル群から目的のファイルを選択する際には,Finderを使ったほうが手早く開けます。

$ 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

このような問題に悩んでいるときに,牧大輔(lestrrat)さんによるpecoや,mattnさんによるchoといったコマンドラインツールの存在を知りました。pecoは標準入力から渡された行をインクリメンタルに絞り込み,選択した結果を標準出力に返すシンプルなツールです。また,choはそのシンプルさをさらに追求し,絞り込み機能を排して[J]キーまたは[K]キーだけで直感的に行を選択できるツールです。これらを自分のプログラムに組み合わせることで,上述の悩みを解消できるのではないかと考えて作ったのがchocoです。

.bashrcの設定

chocoを使うためには,事前にいくつか.bashrcの設定をしておく必要があります。

.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)

まず,Perlのコードからカレントディレクトリの位置を操作しても実際のシェルは影響を受けないので,ディレクトリ間の移動を行うための関数を用意します(1)⁠。また,筆者はこのツールを1日に何度も使用するので,最も打ちやすい[J]キーにエイリアスを割り当てています(2)⁠。この際,不可視ファイルを表示するオプションを付けたエイリアスも設定し(3)⁠,用途によって使い分けています。

使い方

では,実際に使ってみましょう。今回は後述の英語学習ゲームcarvoのリポジトリを例に用います。ルートディレクトリでコードを実行すると,次のようにpecoの選択画面に切り替わり,ディレクトリ内のファイルとサブディレクトリが一覧表示されます。

chocoの実行画面

QUERY>  ――(1)
exit  ――(2)
../  ――(3)
docs/
lib/
local/
src/
t/
Build.PL
ChangeLog.md
(省略)

QUERY(1)で対象を絞り込んだり,選択行を上下に移動したりしながらファイルを選択すると,そのファイルパスが返ります。このときにオプションでopenコマンドを指定しておくと,選択されたファイルが開きます。ディレクトリを選択した場合は,その中に入って同じことを繰り返します。上の階層へ移動したいときは../(3)を選択し,終了する場合にはexit(2)を選択します。

前述のとおり,選択画面にはデフォルトでpecoが使われていますが,オプションでchoを指定することもできます。エイリアスで設定する場合は,次のようにします。

.bashrc

alias jc='choco path/to/choco.pl -c open -s cho'

chocoは今や筆者にとってなくてはならない存在ですが,その中身はwhile文やif文など,初歩的な構文の組み合わせによる100行にも満たないプログラムです。主要な機能を外部ツールに任せたことにより,初めて実現できたツールだと言えます。

特定の文字列を含むファイルを検索する

chocoの応用として,find-word.plというツールも作りました。

これはカレントディレクトリ配下を対象に,特定の文字列を含むファイルを再帰的に検索するツールです。

編集の仕事をしていると,⁠あの語句はどのファイルに記述したっけ……」と探したくなることがたびたびあります。そのようなときに,MacのFinderで検索するのは効率が悪く,かといって心当たりがあるファイルを一つ一つ開いていくのも現実的ではありません。

しかしこのツールを使えば,下階層のすべてのファイルを対象に,短時間で目当てのファイルを探していくことができます。

使い方

対象となるプロジェクトのルートディレクトリでコードを実行します。この際,デフォルトでは選択したファイルのパスを返すだけなので,筆者はopenコマンドでファイルを開くようにオプションを指定し,これをfwというエイリアスに設定して呼び出しています。

.bashrc

alias fw='perl path/to/find-word.pl -c open'

たとえば,先ほどのリポジトリ内でYAMLYAMLAin't Markup Languageを扱っているファイルを探したい場合,ターミナルに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コマンドによって開かれます。

このツールでは日本語の検索もできるので,筆者は表記揺れの検出器としてもよく使っています。