nounai.output(spaghetiThinking);

趣味と実益を兼ねて将棋プログラム(研究ツールなど)を作ってみたいと思う私の試行錯誤とか勉強したことを綴ってゆく予定です。 主目的はプログラミングの経験値稼ぎですが、コンピュータ将棋の製作も目指してみたいとも考えています。

指定範囲行の表示[シェルスクリプト]

テキストの範囲表示をしたい場合はcat, head, tail の組み合わせを使う必要があります(正確には後ろの2つでいけますけど)。そういう時とかにパッとコマンド1つで表示してやりたいなって思いました。まあ簡単なんですけど。


発端

CSAフォーマットの文書がなかなか頭に入りません。しょうがないので、テキスト部分をローカルに保存して

grep -n "^[1-9]\." filename

とかやって章立てを眺めたりします。で、この章の内容どうなってたっけ?って時には"grep -n"して表示された行数を使って元のテキストを範囲表示します。そういう時にコマンドが2ステップ3ステップとか書かなきゃいけないのが気分的にイヤだったのでコマンド1個で完結できるようにしたいな、という所です。

やりかた

まぁ、そこそこCUI(というかシェル)に慣れてるLinuxユーザなら既に調べるまでもなく、って知識でしょうけどね。以下手順。

(1) 範囲行を抽出するスクリプトを書く
作りたいスクリプトのファイル名をncatとでもしましょう。ファイル"filename"の10-30行を表示したい時は"ncat filename 10 30"のように使う感じにします。
> vim ncat
とでも(vim以外のエディタでもいいですけど)して、以下のソースを入力。
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
if test ${#1} -eq 0;then
        echo "usage: ./ncat filename startline endline"
        exit 2
fi

S=$2
E=$3

cat -n $1 | head -n $E | tail -n `expr $E - $S + 1`
とくにエラーチェックはしません。ポイントになるのはバック クォートとexprとかでしょうか。
ちなみに、シェルスクリプトにおいて大体見かける、"#!"で始まる1行目はシェバングと言います。拡張子のないファイルは何ファイルとして解釈(あるいは実行)すればいいの?って情報を伝えるためのもんです。pythonとかのスクリプト言語でもシェバングは記述しますが、今回はbashなのでbashで解釈、実行してね、と言っています。bashのパスが分かってれば(whereis bashとかで調べられます)、"#!/bin/bash"のようにパスを直打ちしても良いです。
(2)作成したスクリプトを適当なディレクトリに移動。
ホームディレクトリとかワーキングディレクトリとか、/usr/local/binとか、適当に。
(3) スクリプトへのエイリアスを作成。
/usr/local/binみたくパスが通ってそうな場所に設置した場合であればやらなくてもいいかもしれません。~/.bash_profileを編集して、
alias ncat="移動後のスクリプトのパス"
の1行を追加します。エディタを閉じて、作業中のコマンドライン上で
source ~/.bash_profile
とすればncatが使えるはずです。

p.s

バッククォートについて

バッククオートで囲まれた文字列はコマンドとして解釈され、自分自身がその実行結果として返ってきた文字列によって置き換えられ(=展開され)ます。C言語で#defineしたシンボルをコード中に書く感じと似てるかもしれません。

exprについて

シェルで足し算などを行う場合、そのまま加減乗除とかの式を書くことはできず、exprをかます必要があります。今回の例ではexprコマンドを使って行数の引き算を行っています。また、用があるのはコマンドの実行結果だけなので、バッククオートで囲んでいます。