「x」で始まる重複行、「x」を「y」に置き換えますか?


9

次のパターンのファイルがあります。

foo 111
baz
foo 222
baz
foo 333
baz

に変える必要がある

foo 111
bar 111
baz
foo 222
bar 222
baz
foo 333
bar 333
baz

したがって、で始まるすべての行を複製し、複製fooのみを変更fooして、残りの行(それぞれの場合で異なる)はそのままにしておきます。これを行う方法?


あなたが正規表現に縛られていなければ、マクロはうまくいきます。このような単純なケースではそれほど重要ではありませんが、もう少し複雑なものがある場合、それは非常に有効な代替手段です。
PhilippFrank

回答:


19

どうぞ:

:g/foo/t.|s//bar

分解:

:g/foo/    " start a global command applied on all lines matching 'foo'
t.         " duplicate the current line (the cursor is now on the new line)
|          " chain a new command
s//bar     " substitute the last searched element with 'bar'

このgコマンドは検索パターンを更新するため、置換コマンドで置き換えるパターンを省略できます。(参照::h :g、を検索search pattern)。


古いバージョン:

:g/foo/norm! yyp:s/foo/bar^M

分解:

:g            start a global command
/foo/         apply only on lines having 'foo'
norm!         execute a normal command
yyp           duplicate the line
:s//bar       replace foo with bar on the line (the duplicated one)
^M            add enter to execute the substitution

^MプレスCtrl+vとを挿入するにはenter

tコマンドについて学ぶ前に、「古い」バージョンを最初に思い付きました。そのままにしておきますが、使用はお勧めしません。最初のものは、より簡潔でわかりやすいです。


解決された、「よりシンプルなバージョン」は完全に機能しました。ただし、最初のバージョンでは、重複する行がfoo...で始まる結果になりました
。– LB7979

奇妙です^M、私が説明したようにあなたは入りましたか?
nobe4

私の悪い、よく読んでいませんでした。最初のソリューションも機能します!
LB7979

どうしてあなたが複雑なバージョンを含めて面倒なのか、まったくわかりません。シンプルなバージョンは...シンプルです。;)(POSIX準拠であることは言うまでもありません。)なぜ最初に配置しないのですか?
ワイルドカード

1
最初は最初のバージョンを思いつきましたが、当時は気付かなかったのでt、2番目のバージョンを追加しました。順序を変更します、あなたは正しいです。最初のものはPOSIXですか?
nobe4

1

私はいつもこのようなことをしていて、ちょうどそのような%s/^foo \(.*\)/foo \1\rbar \1/ことをしています(一部は、コピー機能を使用して巧妙なものに変えることができない多くの同様のタスクも行っており\(.*\)、今では私の筋肉記憶の一部です)。

私はそれがPOSIX準拠ではない(それは他のviクローンでは動作しません)と思いますが、代わりに^MC-VReturn)を使用する\rと、他のほとんどのviクローンでは動作するようです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.