Vim:2行ごとに削除する方法は?


回答:


105

これにはマクロを使用できます。以下をせよ。

  • コマンドモードで起動します。
  • を押して、ファイルの先頭に移動しますgg
  • を押しqqます。
  • 下矢印をクリックし、dd後を押します。
  • を押しqます。
  • 押す 10000@q

PS:コマンドモードに移動するには、Escapeキーを数回押します。


11
もちろん、ファイルの長さが20,000行未満であると仮定します:-)
paxdiablo 2009

3
実はあなたはマイケルの間違いです。ファイルの終わりに達するとすぐにVIがマクロの実行を停止するため、これは問題なく機能します。上記のサンプルで非常に簡単に試すことができます。
rui

1
まあ、他のマクロと同様に、最初は正しく取得する必要がありますが、その後、10000 @ qと入力するだけで、どのファイルにも適用できます。どちらにしても、それは好みの問題だと思うので、断固として哲学的な議論を始めるつもりはありません。:)
rui

3
私は「マクロ」を使用することを好みます。マクロを使用して、1つの特定のタスクをどのように解決するかを「記述」し、VIMにそれを繰り返させます。RUI、矢印キーの代わりに「j」を使用したいと思います。
SolutionYogi

4
:g/^/+dユーザーstackoverflow.com/users/254635/ib(以下)からこれを解決するためのよりエレガントな方法です。
SergioAraujo 2011

254

タスクを実行するためのエレガントな(そして効率的な)方法は、 :+deleteコマンドを使用して、すべての行で現在の行の次の行を削除するコマンド:global

:g/^/+d

10
なぜこの回答がより多くの投票を得なかったのですか?これはとてもクリーンでシンプルです。または、最初の行を削除して上記のコマンドを実行し、奇数行をすべて削除することもできます。
うさぎ

3
@うさぎ:ありがとう!私も同じように感じています。そして、はい、あなたは完全に正しいです:1d|g/^/+d、奇数行を削除します。
ib。

@うさぎ他の回答は、回答が出る2年前の「ベストアンサー」に選ばれました。また、これはより洗練されたソリューションですが、もっと便利な方法で記述できたはずです(つまり、マクロが誰でも簡単に理解できる一方で、^の機能についての言及はありません)。
user1271772 2013年

3
申し訳ありませんが、そのコマンドが望ましい動作を実行する方法の説明がなければ、私はそれを賛成せず、代わりに受け入れられた答えを好みます。それは人に魚を与えることと彼に釣り方を教えることの違いです。
Gabe 2013年

3
わからないけど、この回答で:gコマンドを使って釣りに出かけました(つまり、このページをGoogleで検索しました-vim.wikia.com/wiki/Power_of_g)。
2014

67

:normalまたは:normを使用して、特定の通常モードコマンドを実行できます。ソース。

:%norm jdd

15
この回答と、こことリンクされた乱雑なチートシートの両方で説明が不足しているためか、十分な注意が得られていません。normコマンドは、それに続く文字に相当する通常モードのコマンドを実行します。したがって、ここではjを実行して1行下に移動し、ddを実行して削除しています。これは、この場合にさらに「j」を追加することにより、X行目に一般化できます。
imoatama 2014年

5
%は1、$の省略形です(次のコマンドを1行目から最後まで実行します)
Lambart

3
%norm ddj奇数行を削除したいのになぜ動かないのか興味があります。
Cyker


8

vimメールアーカイブから:

:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile

(vimコマンドラインで1行に入力すると、行1、3、5、7、...が削除されます)


4
それから私は好みます!perl -ne 'print unless $. % 2':-)
アレックスブラセットビク2009

そして、アレックス、私はあなたのソリューションよりも間違いなく私のソリューションを好みますが、これはここでvimのみを使用する唯一の賢明なソリューションであるため、検討する価値があります。
Michael Krelin-ハッカー、2009年

マクロの方がずっと簡単です。
trusktr 2013

+1は、if (expression)3行ごとに機能する柔軟性のため
イェンス

5

常にシェルコマンドを介してパイプすることができます。つまり、好きなスクリプト言語を使用できます。

:%!perl -nle 'print if $. % 2'

(または、必要な行に応じて、「if」の代わりに「unless」を使用します)


-lPerlに切り替える必要はありません...また、awkPerlよりも少し普及していると思いますが、最近はそれほど多くはなく、これをより短くすることができます::%!awk NR\%2または:%!awk 1-NR\%2他の行。
ephemient 2009

4
:%!awk -- '++c\%2'

あるいは

:%!awk -- 'c++\%2'

除草したい半分に応じて。


ええと、なぜ既存のNR変数を使用しないのですか?
ephemient

正しい。忘れていたから。;-)しかし、実際には、「適切な」バリアントはNRでさらに長くなります。そして、見栄えのする対応物は2つありません。
マイケルクレリン-ハッカー、2009年

:%!awk NR\%2または:%!awk 1-NR\%2、別のコメントで投稿したとおり。それはほとんど長くありません。
ephemient 2009

1
1-NRより長いですc++。はい、私はそれが1つのキャラクターであることを知っています。私が言ったように、本当の理由は私がそれを忘れていたということです。とにかく、人々はここのawkの美しさを理解していないようです。
マイケルクレリン-ハッカー、2009年

そして:) NRより短い++c
ephemient

3

Vim独自の検索機能と置換機能を次のように使用できます。最初の行にカーソルを置き、通常モードで入力します。

:.,/fff/s/\n.*\(\n.*\)/\1/g
  • .,/fff/置換の範囲です。これは、「この行から正規表現に一致する行fff(この場合は最後の行)までを意味します。
  • s///代替コマンドです。正規表現を探し、出現するすべてを文字列に置き換えます。のg最後の手段では、限り、正規表現が発見され続けて置換を繰り返します。
  • 正規表現\n.*\(\n.*\)は改行に一致し、次に行全体(.*改行を除く任意の数の文字に一致)、次に別の改行および別の行に一致します。括弧\(\)その中の式が記録されるので、後で使用することができます\1
  • \1 グループ化された改行とその後ろに行を挿入します。これは、次の行も削除したくないためです。置換メカニズムが通過するようにしたいだけなので、次の置換で削除しません。

この方法で、削除を実行する範囲を制御でき、外部ツールを使用する必要はありません。


またはの$代わりに/fff/、ファイルの内容に関係なくファイルの終わりを示します。
ephemient

3

別のアプローチとして、vimがサポートしている場合はpythonを使用することもできます。

:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]

b = cb[:]現在のバッファのすべての行を一時的ににコピーしbます。b[::2]バッファから2行おきに取得し、それを現在のバッファ全体に割り当てcb[:]ます。へのコピーbバッファオブジェクトは拡張スライス構文をサポートしていないようなので、が必要です。

これはおそらく「vimの方法」ではありませんが、Pythonを知っていれば覚えやすいでしょう。


2

奇数行(1,3,5、..)を削除するには-> :%s/\(.*\)\n\(.*\)\n/\2\r/g

偶数行を削除するには(2,4,6、..)-> :%s/\(.*\)\n.*\n/\1\r/g

テキスト(1行目を形成)に続いて改行文字を検索し、さらにテキスト(2行目を形成)に続いて別の改行文字を検索し、上記を最初の一致(奇数行)または2番目の一致(偶数行)に置き換えますその後に改行が続きます。


0

sedを呼び出す:

:% !sed -e '2~2 d'

^^^^                  pipe file through a shell command
    ^^^^^^            the command is sed, and -e describes an expression as parameter
            ^^^^^     starting with the second line, delete every second line

-1

解決

あなたはvimでこれを試すことができます

:1,$-1g/^/+1d

編集する

もっと明確にしようと思います(2つの部分)

最初の部分は選択範囲(:from,to
2番目の部分はアクション(d削除)

  • 最初の行から最後の1行までの範囲(:1,$-1))
  • グローバル(g+1d次の行を削除()

ファイルの最初の行に移動して実行:+1dすると、次の行が消えます。

泥だらけだと知っていますが、vimで動作します


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