複数ファイルから複数行を除くすべての項目を削除する

複数ファイルから複数行を除くすべての項目を削除する

特定のパターンを持つ複数のファイルがあります。

ABCD: 
Something 1 
Anything 2

EFGH:
Something 3
Anything 4

ABCD:
Something 5
Anything 6

HIJK:
Something 7
Anything 8

ABCDの後の2行目を維持し、これらのファイル内の他のすべてのエントリを削除したいと思います。単一ファイルでは、次のコマンドでvimを使用してこれを実行できます。

/ABCD\_[^a-zA-Z] (*searches the pattern*)
qaq              (*flush register*)
:g//norm! "A3Y   (*yank 3 lines including pattern into register A*)
ggVG"ap          (*delete everything else*)

その後、いくつかの簡単な正規表現検索を実行してABCDとSomethingsを削除し、正しいAnythingsを残すことができます。

ただし、推奨事項を使用してargs従っargdoてください。ここ複数のファイルの場合、上記の2番目の操作で「エディタコマンドではありません」というエラーが発生します。 2番目をスキップしてすぐに3番目と4番目に移動しても同じことが起こります。私はあらゆる段階で公演をargsしています。argdo

vimの内部またはそれ以上を維持するための提案はありますか?

答え1

すべてを1つの巨大なnormal!命令に置き換えてください。

:argdo norm! /ABCD\_[^a-zA-Z]<C-v><CR>qaq:g//norm! "A3Y<C-v><CR>ggVG"ap

<C-v><cr>テキストを入力できるキャリッジリターン文字を使用してください。これは問題を解決しますが、アプローチにはまだ欠けていることがたくさんあります。

たとえば、

  • 何かを検索して使用する必要はありません:g//。代わりに使用してください:g/ABCD\_[^a-zA-Z]

  • \_A代わりに使用できます\_[^a-zA-Z]

  • グローバルコマンドに通常のコマンドを実行させる必要はありません。逆に ex 命令を実行すると、レジスタ「a」をクリアする必要はありません。それではそうします:g/ABCD\_A/3ay

あれこれ総合してみるとおすすめですよ

:argdo norm! :g/ABCD\_A/3ya<C-v><CR>ggVG"ap

答え2

以下を使って答えを探しているからですawk

awk '/ABCD/ {getline; getline; print}' input

関連情報