wiki にしていると業者がウザいので生 HTML で行くことにしました。 だからといって更新するようになるわけでもないとは思いますが。 (岸田)
『UNIX今日の技』は、「UNIX 初心者が中級者にレベルアップするための足掛かり」となる事を目的としています。 ですので、「ls って何?」というようなレベルの人はまず本などで(基本的なコマンド程度で良いので)勉強してからにした方が良いと思います。
あと、当研究室特有の事情や研究でよくなされる作業(VASP を使うなど)をそのまま例に挙げることがよくあります。
(今まさに表示されている)このページに書かれているのは最新の記事であり、書いてから暫く時間の経った物は適当なタイミングで archives に放り込んでいます。
たとえば、以下のファイルがあるとします。 (ちなみにこれは VASP の POSCARの一部分で、原子の配置を表しています。)
0.000000000 0.000000000 0.499990000 0.333333333 0.666666666 0.000000000 0.666666666 0.333333333 0.000000000 0.000000000 0.000000000 0.000000000
1行目の 0.499990000 を 0.500000000 に書換えようとして、 「4」の場所にカーソルを合わせたとします。 ここで「cw500000000」で修正してもいいでしょうし、「5s50000」でもいいでしょう。 しかしいずれにせよタイプの数を数えるのが面倒です。 フォーマットを崩したくない場合は連続上書きモード「R」が便利です。 1文字上書き修正の「r」の強力版と考えれば覚え易いと思います。 このファイルの場合、「R50000」で望む結果が得られます。 連続上書きモードで編集すると、例えば「R50000000」でも問題ないのでタイプの回数を細かく気にしなくてもいいので少しラクだと思います。 あと私は、系の対称性を崩すために原子の配置を少しずらす時にもよく使ってます。
まとめると、この手のデータファイルで並びを崩さずに編集したいときに便利ですよー、ということで。
英文を編集していたりすると、「この文字は Capital にしなきゃいけなかった」とかいう場面は頻繁に発生します。 また、定数(大文字ワード)や変数(小文字ワード)、CamelCase を扱っていると、やはり大小文字を書き変えることは少なくありません。 そういう時には「~」での「大小文字変換」が便利です。
たとえば、POSCAR ファイルの 「.FALSE.」を「.false.」にしたければ、「F」の位置で「~....」で用が足せます。
この目的には、範囲選択も利用できます。 「v」「V」「C-v」などで範囲を指定した状態で「~」を打てば、その範囲内の全てのアルファベットの大小が入れ変わります。 (ちなみに、全部大文字にするには「U」、小文字にするには「u」でいけます)
この他に以下のような操作があるらしいですが、私はあまり使ってません。
以上で説明したのと等価なキー操作は以下。打ち易い方だけ覚えれば良いと思います。
「v」や「V」で操作範囲を指定できることは既に紹介しました。 しかし場合によっては単純な「何処から何処まで」では不便なことがあります。
たとえば、INCAR ファイルにおいて、「= の左辺のみを削除したいが各行の = 以降は残したい」場合を想定して下さい。 一つのやり方としては、「8xj.j.j.」が挙げられるでしょう。 また、各行で範囲選択を用いて「v7ldj.j.j.」も悪くありません。 しかし、「C-v」を用いることでもっとスマートに、ビジュアルに編集できます。 PREC の行の頭にカーソルを持って行き、そこで「C-v」、続いて hjkl のカーソル移動、その状態で「d」で削除してみて下さい。 百聞は一見に如かず。 ここで私がグダグダ言うよりも、一度やってみる方が百倍分かり易いでしょう。
なおこのような領域指定の方法は、一般に「矩形選択」と呼ばれています。 Emacs や秀丸などの他のエディタでもしばしば実装されている機能です。 今時は必要なときにインターネット検索すれば済む事が多いので、「矩形選択」という名前を覚えることが一番大事だと思います。 しかし、vim の場合は選択範囲「v」のヴァリエーションということで、コマンドキーを覚え易いのではないでしょうか。
なお、
はそれぞれ、範囲選択中(選択カーソル移動中)に自由に切り替えることができます。 たとえば「v」の範囲選択中に「あ、矩形選択にしておけば良かった」と思ったら、その場で「C-v」してやれば、始点と現在のカーソル位置を対角とする矩形選択に切り替わります。 その状態から元の範囲選択に戻したければ「v」ですし、行指向の範囲選択にしたければ「V」で切り替わります。 ……おっと、現在の範囲選択モードと同じキーを打つと、それは「範囲選択をキャンセル」になってしまいますよ。
追補:
set virtualedit=block
しておくと、「C-v」の矩形選択の際に行末位置より後方にカーソルを置けるようになります。
たとえば、vim のページでサンプルとしている INCAR ファイル
# SCF input for VASP
# Note that VASP uses the FIRST occurence of a keyword
SYSTEM = Untitled (VASP)
PREC = High
IBRION = -1
NSW = 0
ENCUT = 400
NELM = 40
NELMIN = 2
EDIFF = 1.0e-05
EDIFFG = -0.02
VOSKOWN = 1
NBLOCK = 1
ISPIN = 1
INIWAV = 1
ISTART = 0
ICHARG = 2
LWAVE = .FALSE.
LCHARG = .FALSE.
ISMEAR = 1
SIGMA = 0.2
IALGO = 48
LREAL = .FALSE.
において、「VOSKOWN = 1」の行から「ICHARG = 2」の行までを削除したいとしましょう。 パッと以下のような操作が候補に浮かびます。
1, 2 は例えば 100行以上削除する時にはまだるっこしいです。 3の範囲指定「v」を使う方法なんですが、カーソルを行頭に持って行ったり、行末に持って行ったりするのがやや面倒です。 まあ、「0」と「$」の2ストロークだけと言ってしまえばそれだけなんですが。 しかし手間を省くための労力を厭わぬ偉大な魔術師の卵 (既に偉大な魔術師である方は、当然既に知っているでしょう?) の方々には是非「V」を覚えて頂きたいと思います。 「v」の代わりに「V」を用いることで選択範囲は始点終点を含む行単位で指定されることになります。 すなわち、VOSKOWN の行まで移動して「V」、そのまま ICHARG の行までカーソルを移動して「d」 で目的の編集が完了します。
なお、「選択範囲を指定し始めた時には『v』でやってしまったけど、やっぱり『V』にしとけば良かった」という時でも、選択範囲をキャンセルする必要はありません。 選択範囲指定中に「V」を押せば選択範囲の端点はそのままで「行指向の範囲選択」に切り替わります。 逆に「通常の範囲選択」へは「v」で移行できます。
複数ファイルを連続して編集する際、「:n」での次のファイルに移動に対して、前のファイルに戻るには「:N」でいいらしいです。 (情報元: http://zunda.freeshell.org/d/20051020.html#p02。どもありがとうございます。)
別のファイルに移る際に一度編集から抜けた扱いになって、以前の編集履歴は使用できなくなるようです。
以前はエスケープ文字で書かなならんと思ってましたけれど、 どうやら<C-u>みたいな記述でいけるようです。 この方がコピペでデータを移せるので良いですね。 ということで ~ippei/.vimrc を差し替えました。
UNIX今日の技/vi の ~/.vimrc → ~ippei/.vimrc に置いてます。
同時に、「入力モードのキーマップ設定」も少々書き変えました。
imap <C-a> <Esc>:w<CR>a
" ↑保存して入力モードに復帰
私はテキストを一行打つ間にも何度か保存するのが癖になっています。 「[ESC]:w[ENTER]a」 の作業が面倒なので、一つのキーバインドにまとめて快適に保存し ています。
以前はこの動作に [C-w] を当てていたのですが、これだとウィンドウ操作とバッティングしてしまうため [C-a] に当てることにしました。 本当は [C-s] に当てたいのですが、vim に端末停止のコードと解釈されてしまうため、上手く設定できてません。
『UNIX今日の技/UNIXというシステム/UNIXのシステムディレクトリ(の岸田による解釈)』で UNIX のファイルシステムに関する私見を披露概略を説明しましたが、使っている UNIX についてのより厳密な説明を「man hier」によって得ることができます。
「A sketch of the file system hierarchy.」とのことです。
screen セッションを複数開くとどのセッションでどの作業をやっているかが分かり難くなるため、私はいつも1つのセッションだけ開き、それにマルチアタッチして操作しています。 この辺は『マルチアタッチ(screen -x)』の項で紹介しました。 しかし「screen -x」は既に開いているセッションが存在しなければ使えず、「There is no screen to be attached.」と文句を言われてしまいます。
かといって毎回「screen -ls」で開いているセッションが存在するかを確認するのも面倒です。 そこで screen を「screen -xR」として起動してみましょう。 こうすると screen は既に開いているセッションが存在すればそれにマルチアタッチする形で、存在しなければ新しいセッションを作ります。 ここで注意すべきは、オプションの順序が重要になってくることです。 「screen -Rx」では毎回新しいセッションを開いてしまい、望むべく動作しません。
どうしてそうなるか、もうちょっと深く見ていきます。 screen のオプション解析では、-x、-R オプションは指示された順番通りに条件判定を行い、そのオプションで実行できるならそのように実行、そうでなければ単純に無視するようです。
オプション -R は -r と同じくデタッチされたセッションをレジュームするオプションです。 レジュームすべきセッションがない場合、-r オプションではそのまま終了しますが、 -R オプションでは新しくセッションを作ります。
この結果、「screen -xR」では以下のように条件判断していることになります。
ちなみに、私は「alias scr="screen -xR"」として ~/.zshrc に仕込んでいます。
ssh に続けて「192.168.0.1」とか打つのはかったるいなーとか思いませんか? rsync の引数に「q-eng.imat.eng.osaka-cu.ac.jp」とか、あー面倒。
そういう個人的によく使うホスト名をシェル変数 _cache_hosts に登録しておけば、ホスト名が入り得る箇所ではホスト名を補完候補に挙げてくれます。 ホスト名が入り得る箇所というのは例えば、ssh や scp、rsync の引数などですね。
参考までに、私の zsh の初期設定ファイル(~ippei/.zshrc) では以下のようになっています。
_cache_hosts=(localhost $HOST hashish loki3 mercury
Li He Pt Au Ti{1,2} Ni{1,2} Co{1..8} Zn{1..8}
192.168.0.1 192.168.1.1
)
ftp4.jp.FreeBSD.org や mirror.gentoo.gr.jp に頻繁にお世話になるのでしたらこれらを入れといても良いでしょう。 「192.168.……」は入れておくと嬉しい場面がきっとあると思います。
コマンドによっては特定の環境変数を要求するものがあります. しかし環境変数は複数のコマンドに共有される「環境」ですので, あるコマンドでの設定が他のコマンドの設定とバッティングする事があります.
例えば環境変数 LANG はユーザの使用する言語と文字コードを定義しますが, 「日本語 EUC を用いる」という値には歴史的経緯から「ja_JP.EUC」と「ja_JP.eucJP」 の2種類(もしくはそれ以上)があります. vim を日本語で適切に動かすには「LANG=ja_JP.EUC」が必要ですが, wmakerconf は「LANG=ja_JP.eucJP」が必要です. これらのコマンドを正常に動作させるには起動する前に環境変数を変更してやる必要があります.
(LANG が 「ja_JP.EUC」の時) % LANG=ja_JP.eucJP % wmakerconf % LANG=ja_JP.EUC
この場合 wmakerconf が終了した場合には再度「LANG=ja_JP.EUC」に戻してやる必要があります. ここで zsh には一時的な環境変数でコマンドを実行する便利な構文が用意されています.
% LANG=ja_JP.eucJP wmakerconf
環境変数の定義に続けてコマンドを記述すると, コマンドには直前に定義した環境変数が渡されますが, シェル本体の環境変数は変更されません. すなわち「環境変数の戻し忘れ」を予防することができます. もし wmakerconf がよく使うコマンドならば,
alias wmakerconf='LANG=ja_JP.eucJP wmakerconf'
しておくと便利かもしれません.
bash も同じ構文が使えますが, csh 系では無理っぽいです. (もちろん, 以下のように泥臭くやる方法はあります)
setenv temp $LANG;\ setenv LANG ja_JP.eucJP;\ wmakerconf;\ setenv LANG $temp unsetenv temp
コマンドライン編集中に C-w を打つと, 単語単位でバックスペースを実行してくれます.
% ls /usr/local/etc ↓[C-w] % ls
しかし, パス指定の場合は全部消さずに「/」を単語の区切りとしてバックスペースしてもらった方が便利なことが多いです.
% ls /usr/local/etc ↓[C-w] % ls /usr/local/
この目的のためにはシェル変数 WORDCHARS を設定します.
WORDCHARS='*?_-.[]~=&;!#$%^(){}<>'
WORDCHARS は「アルファベット, 数字以外の文字で単語の一部と見做される文字」を保持します. (参照:man zshparam) ちなみにデフォルトは「*?_-.[]~=/&;!#$%^(){}<>」で, 上記の設定はここから「/」を抜いたものになっています.