zshで究極のオペレーションを

第4回 使いこなしポイント 一撃編

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

生成ファイル名の加工

何らかのファイル名のパターン指定が展開され,いくつかのファイル名の集合となるときに,それらをそのまま得るのではなく各ファイル名文字列を各々加工したものを得ることができる。

これにはヒストリ展開のときと同じように,以下の編集子が利用できる。

:h (head)
各ファイル名のディレクトリ名部分のみ取り出す。
:t (tail)
各ファイル名のファイル名部分(最後のスラッシュ以降)のみ取り出す。
:e (extension)
各ファイル名の拡張子部分(最後のピリオドより後ろ)のみ取り出す。
:r (root)
各ファイル名の基幹部分(最後のピリオドより前)のみ取り出す。
:s/OLD/NEW/ (substitute)
各ファイル名の最初に現れる OLDNEW に置換。
:gs/OLD/NEW/ (global s)
各ファイル名のすべての OLDNEW に置換。
:&
直前の置換を繰り返し適用

たとえば *.c(:r) とすると,カレントディレクトリにあるすべての*.c ファイルの拡張子部分を取り除いた名前が得られる。

また,以下のようにするとカレントディレクトリ以下すべてのディレクトリのうち,index.html があるディレクトリのみを選び,そのディレクトリのフルバックアップを tar.gz ファイルに取ることができる。

% tar zcf /tmp/backup.tar.gz **/index.html(:h)

コマンドのフルパス展開

登録されたコマンド検索パスにあるコマンド名の前に `='を付けると,実際に起動されるコマンドのフルパスに展開される。

たとえば,以下のコマンドは,コマンド起動 `ls' によって実際に起動されるプログラムを調べ,仮にそれが /bin/ls だとしたら"/bin/ls"に展開される。

=ls

また,インストールされているコマンドが最新版か確かめたいときなど,以下のようにすると効率的である。

% ls -lF =command

プロセス置換

Unixコマンドは,⁠ファイル名を渡すとそのファイルから読み,渡さない場合は標準入力を読む」という風に設計されているものが多い。しかしながら標準入力は1つしかないので,2つ以上のファイルを同時に処理対象とするコマンドに,フィルタ処理した結果を渡そうとするとテンポラリファイルを作る面倒が発生する。

たとえば,日本語を含む2つのバージョン違いのファイルを diffコマンドで比較したいとする。各ファイルの漢字コードが不揃いなのでEUC-JPに統一してから比較しようとする場合,標準的なシェル作業では以下のような手順が考えられる。

% nkf -e file1 > file1.euc
% nkf -e file2 > file2.euc
% diff -ua file[12].euc | less
% rm file[12].euc

このような場合に,zshのプロセス置換記法の1つを用いると以下のような1文で処理が書ける。

% diff -ua =(nkf -e file1) =(nkf -e file2) | less

zshのプロセス置換には以下の記法がある。

<(CommandLine)
CommandLine を非同期的に起動し,その出力が得られるファイル名/dev/fdや名前つきパイプなど)に置換される。

>(CommandLine)
CommandLine を非同期的に起動し,それへの入力となるファイル名に置換される。
=(CommandLine)
CommandLine からの出力を保存した一時ファイルの名前に置換される。

ブレース展開

ブレース(中括弧; { }は,複数の単語を容易に生成するために利用できる。他のシェルでもたとえば以下のように,前後に置いた単語と,ブレース内にカンマ区切りで列挙した単語を連結した複数の単語に展開できる。

% echo {sta,men,cap}tion
station mention caption
% cp sub/dir/ecto/ry/somefile{,.bak}
(cp sub/dir/ecto/ry/somefile sub/dir/ecto/ry/somefile.bak が実行される)

zshではこれに加え,以下の展開も利用できる。

{m..n}

2つの自然数 m から n までをすべて列挙したもの。

例:

% echo {1..20}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
% echo {01..20}
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20
% echo {001..20}
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020
% echo {12..3}
12 11 10 9 8 7 6 5 4 3
% echo -{12..3}
-12 -11 -10 -9 -8 -7 -6 -5 -4 -3
{c1-c2}

文字c1 から c2までのすべての文字。シェルオプション brace_ccl が必要。

例:

% setopt braceccl
% echo {0-9A-Ma-z}
0 9 A B C D E F G H I J K L M a b c d e f

まとめ

zshが提供する様々な展開は,シェル上の作業で頻繁に登場する典型的な一連の処理を一発で行なえるような工夫が込められている。その他にも多くの展開処理があるので,ひとつひとつ紐解いてゆくことで作業の高速化が期待できる。

次回は,zshの力を特徴づける補完機能について紹介したい。