作曲・指導・C言語・Linux

金沢音楽制作

金沢音楽制作では、楽曲・楽譜の制作と、作曲や写譜などレッスンを行っています。

Vimの置換のメモ

vimのexコマンドで:コマンド/検索文字列/置換文字列/と入力すると、vimに組み込まれたsedが実行されます。通常のsedとかなり似ていますが、vim用に調整されています。ここで例にあげるパターン(検索文字列)は、完全一致にしています。

置換の基本

対象となる文字列

hoge HOGE hoge

置換するには、:sコマンドを使います。sは置換(substitute)の意味です。

そのまま実行すると、カレント行(カーソルがある行)で最初にマッチしたパターン「のみ」が置換されます。

:s/hoge/fuga/
fuga HOGE hoge

行末にgをつけると、カレント行でマッチしたすべてのパターンが置換されます。

:s/hoge/fuga/g
fuga HOGE fuga

行末にcをつけると、確認が行われます。

:s/hoge/fuga/c
replace with d (y/n/a/q/l/^E/^Y)?
行末にiをつけた場合は、大文字小文字を無視して置換します。:set ignorecaseが設定されている場合は、自動で機能します。

:s/hoge/fuga/g
fuga fuga fuga

範囲を指定する

対象となる文字列

#include <stdio.h>
void main(void) {
  printf("hello, world");
  printf("hello, world");
  printf("hello, world");
  printf("hello, world");
}

置換したい文字列が複数ある場合は、一行ずつ置換すると大変です。そこで、範囲を指定して置換します。

:%sコマンドを使うと、1行目から最終行までのファイル全体が対象になります。

:%s/printf/puts/
#include <stdio.h>
void main(void) {
  puts("hello, world");
  puts("hello, world");
  puts("hello, world");
  puts("hello, world");
}

コマンドの前に行番号を付けると、その行が対象になります。

:4s/")/\\n")/
#include <stdio.h>
void main(void) {
  printf("hello, world");
  printf("hello, world\n");
  printf("hello, world");
  printf("hello, world");
}

行番号を:開始行,終了行と区切ると、その範囲の複数行が対象になります。次の例だと、4〜5行目です。

:4,5s/")/\\n")/
#include <stdio.h>
void main(void) {
  printf("hello, world");
  printf("hello, world\n");
  printf("hello, world\n");
  printf("hello, world");
}

行番号のどちらかを省略すると、カレント行の意味になります。

1行目からカレント行までを、カレント行から最終行($)を対象にするには、次のようにします。カレント行は4行目ということにします。

:1,s/printf(/fprintf(stdout, /
#include <stdio.h>
void main(void) {
  fprintf(stdout, "hello, world");
  fprintf(stdout, "hello, world");
  printf("hello, world");
  printf("hello, world");
}
:,$s/printf/fprintf(stderr, /
#include <stdio.h>
void main(void) {
  printf("hello, world");
  fprintf(stderr, "hello, world");
  fprintf(stderr, "hello, world");
  fprintf(stderr, "hello, world");
}

他にも、:a,bs/のように、vimのマーク(m)を利用することもできますし、行選択(V)で範囲を決めることもできます。行選択は、視覚的に確認できることもあって、筆者はもっぱらこの方法ばかり使っています。

文字列の有無で行を削除する

対象となる文字列

#include <stdio.h>
void main(void) {
  // show message
  puts("hello, world");
  // end
}

:g:vコマンドを使って、不要な行を削除することができます。

:gは、対象の文字列がある行を削除します。つぎの例では、//のコメントアウトがある行を削除しています。

:g/\/\//d
#include <stdio.h>
void main(void) {
  puts("hello, world");
}

:vは、対象の文字列がない行を削除します。つぎの例では、//のコメントアウトがない行を削除しています。

:v/\/\//d
  // show message
  // end

改行の扱いについて

対象となる文字列

int main(void) {

  puts("hello, world");
  return 0;
}

改行を追加したり削除する時、ラインフィードは\n^M)、キャリッジリターンは\r^Kを指定します。

改行を削除するときは、\nを用います。

:1s/\n//
int main(void) {
  return 0;
}

応用で空行を削除することもできます。

:s/^ *\n//

改行を追加するときは、\rを用います。例では);の後で改行させています。

:s/);/);\r/
int main(void) {

  puts("hello, world");

  return 0;
}

複数ファイルを対象に置換する

あまり使いませんが、vimで複数のファイルをまとめて置換する方法もあります。:argsでファイルをバッファに読み込んで処理をします。

カレントにあるtxtファイルを全て読み込みます。

:args ./*.txt

:argsで、読み込んだファイルが確認できます。

:args
[test.txt] a.txt b.txt c.txt

読み込んだファイルに問題がなければ、:argdoの引数にsedupdateを記事します。updateがないと、一つずつ保存しなければなりません。なお、この時のsは全体を対象とします。

:argdo %s/hoge/fuga/g | update

更新情報

  • 作成日:2019-xx-xx
  • 更新日:2022-04-30