12

vi / vimで等号の周りにコードを反転させる簡単な方法はありますか?

例:これを回したい:

value._1 = return_val.delta_clear_flags;
value._2._1 = return_val.delta_inactive_time_ts.tv_sec;
value._2._2 = return_val.delta_inactive_time_ts.tv_nsec;
value._3    = return_val.delta_inactive_distance_km;
(...)

これに:

return_val.delta_clear_flags = value._1;
return_val.delta_inactive_time_ts.tv_sec = value._2._1;
return_val.delta_inactive_time_ts.tv_nsec = value._2._2;
return_val.delta_inactive_distance_km = value._3;
(...)

ファイル内の多くの行。

これは少し些細なことのように思えますが、過去にこれを行う必要があったコーディングの際に多くのケースに遭遇しました。 vimで多くの入力をするか、awkスクリプトを書く必要があります。これは、viのワンライナーを介して可能になると思います。

ワンライナーの説明は大歓迎です。受け入れられた回答を選択する際に、非常に注目されます。:)

4

4 に答える 4

29

このようなもの:

:%s/\([^=]*\)\s\+=\s\+\([^;]*\)/\2 = \1

例で示したものよりも複雑なコードがある場合は、少しいじる必要があるかもしれません。

編集:説明

s/検索/置換コマンドを使用します。検索部分は私たちにこれを取得します:

  1. 等号以外の記号で構成される可能な最長の文字列で、[^=]*...で表されます。
  2. ...その後に1つ以上のスペースが続きます(前\s\+の余分な部分はvimの奇妙なものです)\+
  3. ...その後に=、任意の数のスペースが続きます。=\s\+
  4. ...その後に、セミコロン以外の文字の可能な限り長い文字列が続きます。[^;]*

次に、いくつかのキャプチャ括弧を挿入して、置換文字列を作成するために必要なものを保存します。これが\(スタッフ\)の構文です。

そして最後に、findreplaceコマンドのreplace部分でキャプチャされた文字列を使用しますそれとです。s//\1\2

于 2009-09-03T15:30:45.763 に答える
11

興味のために、これが私が記録されたマクロとしてそれをした方法です:

qq0"+df=xA<BACKSPACE> = <ESC>"+pxi;<ESC>jq

最初の行でそれを実行すると、「q」マクロが必要なことを実行するように設定されます。次に、後続の各行で、次のように入力してマクロを実行できます。

@q

または、マクロを次の10行に適用するとします。

10@q

マクロは、基本的に手動で行う方法の拡張であるため、正規表現を理解するよりも、このようなクイックスイッチの方が簡単だといつも思っています。

編集:Dan Olsonはコメントの中で、マクロを行の範囲、たとえば6〜100行に適用する場合は、次のように入力できると指摘しています。「。*」パターンマッチを必要としない、より簡潔な構文があるかどうかはわかりません。

:6,100g/.*/normal @q

マクロの説明

  • qq
    • レジスタqでの記録を開始します
  • 0
    • 行頭に移動
  • "+ df =
    • '='まで削除し、テキストを'+'レジスタに入れます
  • バツ
    • 余分なスペースを削除する
  • A
    • 行末に移動して挿入モードに入ります
  • <BACKSPACE>=<ESC>
    • セミコロンを削除し、等号とスペースを挿入します
  • "+ p
    • 以前にコピーしたテストをレジスタ'+'に挿入します
  • xi;<ESC>
    • 末尾のセミコロンを再挿入します
  • j
    • 次の行に移動して、マクロを再適用する準備をします
  • q
    • 録音を停止します
于 2009-09-03T16:12:38.893 に答える
4
:%s/^\s*\(.\{-}\)\s*=\s*\(.\{-}\)\s*;\s*$/\2 = \1;/

うまく動作するはずです。

于 2009-09-03T15:49:36.747 に答える
0
:%s/\([^ =]*\)\s*=\s*\([^;]*\);/\2 = \1;/
于 2019-01-26T10:11:44.633 に答える