繰り返し
編集作業では統一しないといったことはまずありません。変更を行う場合には複数回 それを繰り返さなければならないこともよくあります。この章では変更を繰り返して 行う便利な方法について説明します。
|26.1| ビジュアルモードでの繰り返し |26.2| 加算と減算 |26.3| 多くのファイルに変更を加える |26.4| シェルスクリプトでvimを使う
Next chapter: |usr_27.txt| 検索コマンドと正規表現 Previous chapter: |usr_25.txt| フォーマット付きテキストを編集する
Table of contents: |usr_toc.txt|
==============================================================================
ビジュアルモードはあらゆる組み合せに対して変更を加えるためのとてもお手軽な方 法です。選択範囲はハイライト表示になりますから、変更を加えた行が正しいのかど うかを確認できます。ですが、選択をするには多少の打鍵が必要です。"gv"コマンド で同じ範囲の領域を再選択できます。これを使うと同じ範囲に対して別の処理を実行 させることができます。 例えば、以下の文の"2001"を"2002"に変更し"2000"を"2001"に変更したいとします。
The financial results for 2001 are better ~ than for 2000. The income increased by 50%, ~ even though 2001 had more rain than 2000. ~ 2000 2001 ~ income 45,403 66,234 ~
まず、"2001"を"2002"に変更します。ビジュアルモードで上の範囲を選択し、次のコ マンドを実行します。 >
:s/2001/2002/g
次に"gv"で同じ範囲を選択します。その時のカーソル位置を気にする必要はありませ ん。次に":s/2000/2001/g"で2回目の変更を行います。 当然ながら、同じやり方で何度でも変更を繰り返すことができます。
1つの値を別の値に変更することを繰り返すには、いくつも固定値を指定しなければ なりません。上の例で言えば、各年を1づつ増やしたいわけです。何度も置き換えコ マンドを入力して年を指定する代わりに、CTRL-A コマンドを使うことができます。 上と同じ文章に対して年を検索するコマンドを実行します。 >
/19[0-9][0-9]\|20[0-9][0-9]<Enter>
ここでCTRL-Aを押します。するとカーソル位置の数字が1増えます。
The financial results for 2002 are better ~ than for 2000. The income increased by 50%, ~ even though 2001 had more rain than 2000. ~ 2000 2001 ~ income 45,403 66,234 ~
次に"n"コマンドで次の年を探し、"."コマンドでCTRL-Aを繰り返し("."の方が少々打 ちやすいですから)ます。"n"と"."を繰り返して文章中の全パターンを置き換えます。 Hint: 変更しようとしているパターンに合うものを見たければ、'hlsearch'オプショ ンをonにします。すると早くパターンを見つけられますから、作業もはかどるでしょ う。
増加分を2以上にしたい場合はCTRL-Aの前に数を指定できます。次のような文章があ るとします。
1. item four ~ 2. item five ~ 3. item six ~
カーソルを"1."のところに動かし、こう入力します。 >
3 CTRL-A
すると、"1."は"4."に変わります。これを繰り返すには他の数字で"."を使ってくだ さい。
もう一つ例を示します。
006 foo bar ~ 007 foo bar ~
上の数字のところでCTRL-Aを使えば、結果はこうなります。
007 foo bar ~ 010 foo bar ~
7+1が10?何が起ったかというと、vimは"007"というのは先頭に"0"があるので8進数 だと考えたためです。(8進数では7の次が10となりますよね) これと同じことはCプログラムでもよく言われます。もし先頭に"0"がある数字を8 進数として処理させたくないのであれば、こうしてください。 >
:set nrformats-=octal
なお、CTRL-Xコマンドは減算コマンドとして同じように使えます。
==============================================================================
あるプログラムで"x_cnt"という変数を使っており、これを"x_counter"に変更したい としましょう。この変数はいくつかのCソースファイルで使っています。ですから、 該当する全ファイルを変更しなければなりません。ここではその手順を説明します。 まず関連しそうな全ファイルを引数(argument)リストに加えます。 >
:args *.c
これで全Cソースファイルが対象となり、最初のファイルが編集画面に出てきます。 ここで置換コマンドをその全ファイルに対して実行するのです。 >
:argdo %s/\<x_cnt\>/x_counter/ge | update
":argdo"コマンドは何らかの他のコマンドを引数に取ります。指定のコマンドは引数 リストの全ファイルに対して実行されます。 "%s"は全行を対象とした置換コマンドです。"\<x_cnt\>"の指定で"x_cnt"という単語 を探します。"\<"と"\>"は"px_cnt"や"x_cnt2"を除外し、単語としてヒットするもの だけを抽出します。 置換コマンドで使っている"g"フラグは1つの行で複数回"x_cnt"が現われた時に全部 を置換するという指定です。"e"フラグは"x_cnt"があるファイルで見つからない時に エラーメッセージを表示するのを抑制します。これがないと、":argdo"は"x_cnt"が 含まれていないファイルを処理した時点で中断してしまいます。 "|"はコマンド間のセパレータです。次の"update"コマンドは変更があった時にだけ ファイルを保存します。"x_cnt"から"x_counter"への変更がない時には何も起りま せん。
他に":windo"というコマンドがあります。これは全ウィンドウを引数として処理を実 行します。また":bufdo"もあり、これは全バッファを引数とします。これを使うのは 気をつけてください。バッファリストにあるファイルは使っている人が思っている以 上にある場合があります。 ":buffers"コマンド(か":ls"コマンド)で確認をしてください。
==============================================================================
JP:注 この章の記述はUnix系OSでのみ有効です。 例えば、"-person-"という文字列を"Jones"に置き換えて印刷する必要があり、対象 となるファイルが大量にある場合を思い浮べてください。どのようにして実行すれば よいでしょう?一つは大量のタイプを厭わない方法です。もう一つはそれを行うシェ ルスクリプトを書く方法です。 vimは通常モードのコマンドを使って、スクリーンエディタとしては見事にこの作業 を片付けます。ですが、バッチ処理用としては通常モードコマンドはあまりにもわか りにくいでしょう。ですから代りにExモードのコマンドを使います。このモードでは バッチファイルとの親和性の高いコマンド行単位のインタフェースを提供します。 ("Exコマンド"というのはコマンド行コマンドとかコロンコマンドと呼ばれるものの 別称です) 必要となるExモードのコマンド例を示しましょう。 >
%s/-person-/Jones/g write tempfile quit
こういったコマンドを"change.vim"に格納しておきます。次にシェルスクリプトから vimをバッチモードで起動します。 >
for file in *.txt; do vim -e -s $file < change.vim lpr -r tempfile done
"for"〜"done"のループは、間にある2つの行を繰り返し実行するシェル構文です。 変数$fileには繰り返しの都度、違ったファイル名が入ります。 2行目はvimを(-eパラメタで)Exモードで実行します。対象となるファイル名は$file での指定となり、実行するコマンドは"change.vim"から読み込みます。"-s"パラメタ はvimが寡黙モード(非会話モード)で実行します。言い換えると":" プロンプトやそ の他のプロンプトは全く表示しないということです。 "lpr -r tempfile"というコマンドは出力結果の"tempfile"を印刷した後でそれを削 除します。("-r"パラメタがその意味です)
標準入力からの読み込み
vimは標準入力から文章を取り込むことができます。通常は標準入力からはコマンド を読み込みますので、そうでないことをvimに伝えなくてはなりません。これはファ イル名の代わりにパラメタとして"-"を与えることで行います。例えばこうです。 >
ls | vim -
これで、"ls"コマンドの出力結果をファイルに保存したりせずに、直接編集できま す。 標準入力から文章を読み込む場合でも、"-S"パラメタを使えば、スクリプトを読み 込ませることができます。 >
producer | vim -S change.vim -
通常モードのスクリプト
どうしもてスクリプト中で通常モードのコマンドを使いたい場合は、このようにする ことで可能です。 >
vim -s script file.txt ...
Note: "-s"パラメタを"-e"なしで使う場合は違った意味になります。つまり、スク リプトを通常モードコマンドとみなして取り込みむという意味になります。 "-e"といっしょに使った場合は寡黙モードであることを示し、ファイル名の ようなパラメタは取りません。
"script"中のコマンドはvimを起動して実際に入力したのと同じように実行されます。 スクリプト中の改行記号も実際にvimの編集中に<Enter>を押したのと同じように処理 しますので注意してください。なお、<Enter>は通常モードではカーソルを次の行に 動かすコマンドです。 スクリプトを作るにはそのファイルを開いて、コマンドを入力することで作成できま す。ただ、そのコマンドの結果を頭でイメージしながらになりますので、多少難しい でしょう。 もう一つ方法があって、実際にその作業を行っている間コマンドをレコード(記録)す るのです。その手順を説明しましょう。 >
vim -w script file.txt ...
これで入力した全ての操作は"script"ファイルに保存されます。多少のミスがあって も操作を続けて、後でそのミスを思い出して、スクリプトを修正すれば良いでしょ う。 "-w"パラメタは既存のスクリプトに追加します。ですから、少しづつ少しづつスクリ プトに記録したい時には便利でしょう。何もない状態から作り始めるのなら、"-W"パ ラメタを使ってください。これは既存のファイルに上書きします。
==============================================================================