2013-04-17 12 views
8

ファイルを検索して文字列を検索し、その文字列を含む行を削除し、その文字列を含む行に続く2行を削除する必要があります。私はgrepの-vフラグと-Aフラグの組み合わせ

$ grep -v -A 2 two temp.txt 
one 
five 
$ 

このような何かを...使用してこれを実現する可能性が期待していた...残念ながら、これは動作しませんでした。 grepや別のシェルコマンドでこれを行うことは簡単ですか?

答えて

5

GNUのsedのとOS Xに2行以上

  • two
  • 読み取りに一致

    $ sed '/two/{N;N;d;}' temp.txt 
    one 
    five 
    
    • 検索ラインはGNUで彼らに
  • +0

    あなたの答えと@ JohnKugelmanの両方は簡潔で、どちらもGNU/Linuxで動作し、どちらもOS Xで動作しません。構文の簡単な説明を提供するために、受け入れられた答えはあなたに行きます。ありがとう。 –

    +2

    dとdの後にセミコロンを追加します。ブレースを強制すると、MacOS Xでもうまくいくはずです。 –

    2

    を削除すると、次の両方の作品sed:

    sed '/two/,+2d' temp.txt 
    

    2つのアドレス構文(addr1,addr2)を使用して、単語2(/two/)と2行の後に(+2)の行を一致させます。 dコマンドは、これらの行を削除します。

    +0

    私が考えることができるのは、 '+ number'オプションなしで古いGNU sedを使っているのかもしれないということだけです。しかし、それが動作する(そして、私はドライブバイダウンボートを嫌う)、それを逆転するための投票があります。 – paxdiablo

    3

    次転写物あたりのようにして、awkでこれを行うことができます:それは基本的に、それはライン上two文字列を見つけたときに(3)を捨てるためにラインのカウンタをスタート

    pax> echo 'one 
    two 
    three 
    four 
    five' | awk '/two/ {skip=3} skip>0 {skip--;next} {print}' 
    
    one 
    five 
    

    。その後、スキップカウンタがゼロになるまでそれらの線を放ります。スキップされていない行はすべて印刷されます。ここで

    +0

    これは正しく 'one two three three two four five five'→' one five'を正しく扱うという利点があります。 –

    1

    は、Perlでそれを行う方法です:

    $ perl -ne'if (/two/){$x=<>;$x=<>;}else{print}' temp.txt 
    one 
    five 
    

    -nは、入力オーバー暗黙のループです。 /two/と一致する場合は、次の2行を読んでください。それ以外の場合は、その行を印刷してください。

    ただし、3行目または4行目が/ 2 /と一致しても、同じ出力が得られるという問題があります。 @ paxdiabloのソリューションはより完全です。しかし、私の多くQ & D.

    関連する問題