行にあるグローバルexコマンドのパターンを使用して、別の行で置き換えます


8

私のfortranコードには、次のような多くのブロックがあります

subroutine name(arg1,arg2,arg3,...)
:
end subroutine

そして私は彼らになってほしい

subroutine name(arg1,arg2,arg3,...)
:
end subroutine name

これらの各ブロックは、任意の量のスペースでインデントできます(実際、そのようなブロックはネストできます)。コマンドで試してみました

:g/^ *subroutine \(.*\)/;/end subrout/s/end subroutine/& \1

バッファ\1が空であるように、これは各行を変更します(一番下の行でそれを読みます)。コマンド

:g/^ *subroutine \(.*\)/;/end subrout/s/end subroutine/& hello

うまく機能しますが、明らかに私が望んでいるものではありません。だから問題は、グローバルexコマンドで一致したパターンを置換文字列でどのように使用できる:gかです。

編集 質問を編集しているのは、投稿した時点で、私が参照した特定のケースに対する回答である回答を急いで受け入れたが、質問のタイトルは少し一般的ではなかったためです。

私は要点に行きます。私は次のようなファイルを持っています(できるだけ一般的にするだけで意味がありません)。

# sec1
fun1  are you a function?
fun2 no.
fun3 ok, nice to meet you!

# 2nd part
first line
third line
ops (it was the second)
there were 3 lines in the preceding #

# fourth group
now there's just one
and foreveeer

(実際、各#-lineに続く行は数百です。)

#-lineに続く(そして次の#-lineに先行する)すべての行で置換を行わなければなりません。これらの置換はすべて、先頭の#行(またはその一部)の後のテキストを使用する必要があります。私が達成したい一例は

# sec1
fun1 in sec1  are you a function?
fun2 in sec1 no.
fun3 in sec1 ok, nice to meet you!

# 2nd part
first in 2nd line
third in 2nd line
ops in 2nd (it was the second)
there in 2nd were 3 lines in the preceding #

# fourth group
now in fourth there's just one
and in fourth foreveeer

#次の行には、最初の単語だけが挿入されることに注意してください。

だから、すでに言ったように、:gコマンドのパターンが代替文字列で使用できるかどうか知りたい。マクロを登録するのは非常に煩わしいので、この答えにとても興味があります(1つの間違ったキーストロークは最初からやり直すことを意味します)。

:g/^# \(\<\w\+\>\)/+;/^#/- s/\(\<\w\+\>\)\(.\+$\)/\2 \1 \3

完璧になります!...そして、私が仕事をするコマンドを使用する方法がないことを信じるのは難しいです!

回答:


4

あなたは、の組み合わせを使用することができ:globalmatchit:normal!

:g/^\s*subroutine/norm ^whye^%$p

説明:

  • :g/^\s*subroutine:に一致するすべての行に対して^\s*subroutine、次を実行します。
  • normal:通常モードに入る(! マッピングがないことを意味しますはmatchitの呼び出しを削除するため、使用しないでください(@SatoKatsuraに感謝))norm!!
  • ^最初の非空白文字に移動します(0ネストされたサブルーチンを処理するためではなく)
  • whye:2番目の単語(名前)に移動し、1文字(スペース)戻ってコピーします(スペースは、末尾の貼り付けを少し簡単にするためです)
  • ^%:最初の空白以外の文字に戻り、matchitを使用して一致するものを検索します end
  • $pname行の終わりに(先頭に空白を入れて)貼り付けます

2
norm!%からの殺害matchit。ソリューション::%g/^\s*subroutine/norm ^whye^%$p
佐藤桂

ああ、そうだね。私は実際にそれをテストしましたが、ここでは干渉するカスタム設定がないとかなり確信していたので、のnorm代わりに使用しnorm!ました…良いキャッチ、そして修正に感謝します。
2016

3
@SatoKatsura:を使用する必要がある理由がわかりません:%g。個別のネストされたサブルーチンを使用して(およびを使用して-u NONE)両方のバッファーを試したところ、どちらの場合も同じ結果が得られました。私:globalのデフォルトの範囲は1,$(つまり%)でした。どのような場合に%違いが生じますか?
2016

5

可能な回避策はマクロを使用することです:

qa/^subroutine<CR>f<space>/end subroutine<CR>$pq

これは次のように詳細化できます:

qa                  Record a macro in the a register
/^subroutine<CR>    Go to the next occurence of a subroutine declaration
f<space>            Go to the space separating "subroutine" and the name
y$                  Yank till the end of line (i.e. the name)
/end subroutine<CR> Go to the next occurence of "end subroutine"
$p                  Put the name at the end of the line
q                   Stop recording the macro

あなたは、その後で、あなたのマクロを実行することができますX@aどこXのサブルーチンの数が進むことです


1
まあ、私はたくさんのマクロ(レジスタcでコメント、uでコメント解除、tでタブなど)を使用しているので、もう1つのマクロは問題になりません。とにかく、私の考えでは、マクロを気づかずに意味のないもので誤って上書きしてしまう可能性があります(qはwに近く、私はまだタッチタイピングの達人ではありません)。それで、今のところ、私は他の答えを期待する/待つつもりです。
エンリコマリアデアンジェリス

2
Fortranは、ネストされたサブルーチンを持つことができます。
佐藤桂

4

@statoxによるマクロソリューションは次のとおりです。サブルーチンのパラメーターとネストされたサブルーチンを処理するように変更されています。これは、matchitもインストールしていることを前提としています。

  • qaq -レジスタをクリア @a
  • qa -レジスタに記録を開始 @a
  • /^\s*subroutine\zs<CR>-を検索しsubroutineます。\zsその後ろのスペースにカーソルを置きます
  • y2w-名前をヤンクします。2スペースを含めwたいので、word(これは(などで停止します)
  • h -左へ、最後まで subroutine
  • %-マッチングに行くend subroutine(の3つの応援matchit
  • $p -名前を貼り付け
  • _ -最初の空白以外の文字、つまり(the)の先頭に移動します end
  • % -マッチングに戻る subroutine
  • j-ダウン、さらにsubroutines を探す
  • 0- subroutine現在の行のaを見逃さないように、行の先頭に移動します
  • @a -現在のマクロを再帰的に呼び出す
  • q -終了マクロ

それを実行するには:

  • :set nowrapscan -無限ループを回避する:マクロがファイルの最後に到達すると、マクロがベイルアウトします
  • 1G -ファイルの先頭に移動
  • @a -マクロを実行する

3

あなたは代わりのコマンドで行くことができます:

:%s/\v(^subroutine (.+)\_.{-}end subroutine)/\1 \2

これsubroutine / end subroutineは、グループ1の全体とグループ2のサブルーチン名に一致し、それらを連結します。

{-}非貪欲である*最初の要素が見つかった時にそれが停止しますので。

\_.すべてと一致しますnew-line


2
これは機能しません。Fortranはサブルーチンをネストできます。
佐藤桂

1
わかりましたが、OPはそれについて何も指定していません。彼の命題と他の答えは、ネストされたサブルーチンでは機能しません。「クロージング」サブルーチンを一致させることは、まったく別の問題です。
nobe4

2
大した問題ではなく、matchitネストされたサブルーチンを処理できます。
佐藤桂
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.