シェルやコマンドは繰り返し使うことで手に馴染む、まさに道具のような存在なのだが、不慣れな人には「こういう場面でこれを使う」というシチュエーションを示したほうが理解しやすいはず。前回前々回に続いて「機能逆引き」の流儀に従い、OS Xに標準装備されているコマンドのみを頼りに知ってトクする使い方を紹介してみよう。

特定範囲から数字をランダムに選ぶ

数字をランダムに選ぶ場面は、意外に多い。学校の同じクラスのなかから3人選ぶとか、職場のチームから2人選ぶといった場面で、急きょクジをつくった記憶を持つ人も多いはずだ。

これをOS Xで実行しようとすれば、jotコマンドを使うといい。クラスの出席番号、あるいはオフィスの席のように、番号と氏名の関係が周知の状態にあることが条件だが、「jot」コマンドだけで要求を満たしてくれる。

使い方はかんたん。たとえば、1から40の範囲からランダムに5つの数字を抽出するには、以下のとおりコマンドを実行する。「-r」オプション直後の値は抽出件数を、「1 40」は範囲を指す(省略すると1~100)。10~20の範囲から2つの数字を選ぶのであれば「-r 2 10 20」、1~100の範囲から3つの数字を選ぶのであれば「-r 3」とすればOKだ。なお、乱数は同じ範囲から繰り返し抽出されるため、重複することがあるので注意しよう。

$ jot -r 5 1 40

指定した範囲からランダムに数値をピックアップできるが、重複してしまうことがある

特定範囲から重複しない数字をランダムに選ぶ

特定範囲から乱数を得るときjotコマンドを使う方法は、覚えやすく手っ取り早いが、重複することがあるのが難点。誰かに"貧乏クジ"を引かせる用途に使うときなど、繰り返しコマンドを実行すれば非難されること必至、1回勝負で決めることが望ましい。

そんなときは、少々長めのコマンドになるが、perlスクリプトを使うといい。Perl標準の配列操作ライブラリ「List::Util」に含まれるshuffle関数を使い、示した範囲の数字を標準出力へアウトプットし、その先頭から3行をheadコマンドで抽出し画面に書き出す、という仕組みだ。Excelで同様の処理をしようとすると、VLOOKUP関数を使うなど手間がかかるが、こちらの方法であればコマンドライン1行で済む。より効率的と思うが、いかがだろうか。

$ perl -MList::Util=shuffle -e 'print join"\n",shuffle(1..40)' | head -3

1~40のなかから3つの数値をランダムにピックアップ。重複しないところがメリットだ

余りのある計算を行う

「100÷15」といった(整数では)余りが出ること確実な計算を行うとき、どうしているだろうか? そのまま電卓を使ってしまえば、小数点以下まで計算されてしまう。知りたいのは商ではなく剰余、という場合には役に立たない。

そんなときは、シェル(bash)に組み込みの演算機能を使えば一発だ。echoまたはexprコマンドに「$((整数A % 整数B))」という引数を与えるだけで、剰余がわかる。前述の例でいえば、「$((100 % 15))」と記述すればいい。実はSpotlightやGoogle検索でも同じことができるのだが、次の設問でシェルの計算式を使うため、前振りということでご理解いただきたい。

$ expr $((100 % 15))

シェルの機能で四則演算する方法を覚えておいて損はない

フォルダ/ファイルの個数をカウントする

ある領域上のファイル/フォルダの個数を数える作業は、Finderを使えばわけもないことだが、Terminalでは意外に手間がかかる。しかし、理屈さえわかれば難しいことはない。

lsコマンドに「-l」オプションを付けると、引数に与えた領域上のファイル/フォルダが一覧されるが、先頭に「Total XXXX」とファイルサイズの合計値まで表示されてしまう。この行さえなければ、「ls -l」で出力された行数をwcコマンドでカウントすると、ファイル/フォルダの個数がわかるのだが……。

そこで利用するのが、先ほど紹介したexprコマンド。「ls -l」の出力結果を「wc -l」にパイプし、その値から1を引くという寸法。タネを明かせばどうということもない話だが、コマンドも組み合わせ次第でいろいろなことができるという好例だ。

$ expr $((`ls -l | wc -l` -1))

カレントディレクトリに存在するファイル/フォルダ(先頭が「.」で始まるものを除く)の個数を表示する

フォルダのみ/ファイルのみの個数をカウントする

ファイル/フォルダを一覧するコマンドには「ls」が用意されているものの、UNIXでは伝統的にファイルとフォルダ(ディレクトリ)を明確に区別しないためか、ファイル/フォルダそれぞれに絞って一覧することができない。前述の方法では、ファイル/フォルダを分けて数えることは困難だ。

しかし、目先を変えてみよう。lsコマンドでは、「-F」オプションを付けるとフォルダの末尾には「/」が付く。これが行に含まれるかどうか判定すれば、フォルダのみ抽出できるというわけだ。つまり、lsコマンドの出力結果をgrepコマンドにパイプすればOK。それをさらにwcコマンドにパイプすれば、フォルダの数がわかる。なお、「ls -F」はTotal行を出力しないので、引き算する必要はない。

$ ls -F | grep / | wc -l

ファイルの個数を調べる場合はフォルダ以外の行、すなわち指定した文字列とマッチしなかった行を表示するオプション「-v」をgrepコマンドに付ければいい。実行例は以下のとおり、これでカレントディレクトリにあるファイルの個数がわかるはずだ。

$ ls -F | grep -v / | wc -l

カレントディレクトリに存在するファイル/フォルダ(先頭が「.」で始まるものを除く)それぞれの個数を表示する