2009-08-04 1 views
11

[社説挿入:同じポスターのearlier questionの可能性のある重複?]bashのはgrepの改行

こんにちは、私はファイルから抽出する必要があります。grepコマンドを使用して

first 
second 
third 

、次の行:

second 
third 

grepコマンドはどのように見えますか?

+0

これを文字通り意味するのでしょうか、それとも2番目と3番目の行彼らはどんなコンテンツを持っていますか?また、これはあなたの宿題ですか? – Telemachus

+0

私の宿題ではなく、ただの仕事です。私はここで正規表現をどのように構築するのか正確にはわかりません。 – Markus

+1

私が望むのは、改行文字を含む正規表現を構築することです。 – Markus

答えて

1

Line?またはライン? grepの行に配向される:

grep -E -e '(second|third)' filename 

編集してください。 Perl、sed、awkのいずれかを使って行間のパターンマッチを実行する必要があります。

BTW -E regexpが拡張されていることをgrepに伝えます。

+0

行。しかし、egrepで使用される正規表現の作成はどうですか?改行文字はどのように表現されていますか? – Markus

+0

'egrep 'second \\ nthird' filename' –

0
grep -E '(second|third)' /path/to/file 
egrep -w 'second|third' /path/to/file 
2

私は本当に何を一致させたいのか分かりません。私はgrepのを使用しますが、次のいずれかではないでしょう:

tail -2 file   # to get last two lines 
head -n +2 file  # to get all but first line 
sed -e '2,3p;d' file # to get lines from second to third 

(それがどのように標準わからない、それは確かにGNUツールで動作します)

+0

私は同意します。 grepは実際にこれを行う正しい方法ではありません。 – Jim

8

ご質問抽象「のbash grepの改行」、ということを意味しますsecond\nthirdの文字列、つまりその中に改行が含まれているものと照合したいでしょう。

grepが "lines"で動作し、これらの2つの行が異なるため、このように一致させることはできません。

だから、私はいくつかのタスクに分割したい:

grep -A 1 "second" testfile 
    1. あなたは「第二」含む行と出力一致した行と次の行にマッチ

      あなたは他のすべての改行を、入力では発生しないことが保証されているシーケンスに変換します。私はそれを行うための最も簡単な方法は、Perlを使用していると思う:

      perl -npe '$x=1-$x; s/\n/##UnUsedSequence##/ if $x;' 
      
    2. あなたは、この時間は、文字列##UnUsedSequence##thirdを探し、これらの行にはgrepを実行します。

      grep "##UnUsedSequence##third" 
      
    3. あなたが戻って、未使用のシーケンスをアンラップ

      sed -e 's/##UnUsedSequence##/\n' 
      

    ので:改行に、SEDは、最も簡単かもしれませんあなたが望むことをするパイプコマンドは、次のようになります。

    grep -A 1 "second" testfile | perl -npe '$x=1-$x; s/\n/##UnUsedSequence##/ if $x;' | grep "##UnUsedSequence##third" | sed -e 's/##UnUsedSequence##/\n/' 
    

    これまでのところ最もエレガントではありませんが、動作するはずです。私はより良いアプローチを知りたいと思っていますが、何かあるはずです。

  • 1

    「最初の」行が含まれないようにするだけですか? -vはgrepの結果を反転します。

    $ echo -e "first\nsecond\nthird\n" | grep -v first 
    second 
    third 
    
    3

    私はのgrepはこれに移動するための方法だとは思いません。

    ファイルから最初の行を削除するだけで(質問を一般化するため)、代わりにsedを使用します。

    sed '1d' INPUT_FILE_NAME 
    

    これは、ファイルの内容を最初の行を削除して標準出力に送信します。

    次に、標準出力を別のファイルにリダイレクトして結果を取得することができます。

    sed '1d' INPUT_FILE_NAME > OUTPUT_FILE_NAME 
    

    これはすべきです。あなたがそれに最初の行を表示したくないグレップだけを使用する必要がある場合

    、これを試してみてください。

    grep -v first INPUT_FILE_NAME 
    

    -vスイッチを渡すことで、 grepには、あなたが渡している表現が表示されますが、と表示されています。実際にはの最初の行を除くすべてのものを表示してください。

    最初にのファイルが他の行も表示されず、期待している動作ではないことが欠点です。このしようと、新しいファイルに結果を分流する

    grep -v first INPUT_FILE_NAME > OUTPUT_FILE_NAME 
    

    は、この情報がお役に立てば幸いです。

    +0

    最後の2つの例が後方にあると思います。 – Telemachus

    +0

    それをキャッチするためにありがとう。 – Jim

    20

    代わりのgrep、あなたがpcregrepを使用することができます

    pcregrep -M 'second\nthird' file 
    

    -M複数行のパターンをサポートするパターンが複数の行を一致させることができます。

    +4

    ファイル内の行末に応じて '\ n'の代わりに' \ s + 'を使うことができます(' \ r \ n 'でもよい) – davemyron

    0

    あなたの前と後に一致し、1つの文字列で文字列を出力します

    $ grep -1 third filename 
    

    これを使用することができます。最後の文字列に "third"があるので、最後の2つの文字列を取得します。

    0

    私はnotnoop's answerを好きですが、(pcregrepない人のためのより良いですが、あまりにも複雑なもの)AndrewY's answerに構築し、あなただけ行うことができます:-vフラグは試合を反転

    RESULT=`grep -A1 -s -m1 '^\s*second\s*$' file | grep -s -B1 -m1 '^\s*third\s*$'` 
    
    0
    grep -v '^first' filename 
    

    を。

    1

    grep -A1 "second" | grep -B1 "third"はうまく動作し、複数のマッチがある場合でも元のマッチデリミタを取り除くことさえあります

    関連する問題