テキスト\行のブロックによるGrep

テキスト\行のブロックによるGrep

いくつかの行を含むテキストがあります。そのため、いくつかの行を GREP する必要があります。たとえば、繰り返しテキストがあり、この繰り返しキーワードを含む行を GREP で取得する必要があります。

grep -o "test|test2" textfile

私のテキスト:

123|never for your|test
123421|never for your|test2
123412|never for your|test3
12341|never for your|test4
12311|never for your|test2
123312312|never for your|test
123321312|never for your|test2

私が持っている必要があります:

123|never for your|test
123421|never for your|test2
123312312|never for your|test
123321312|never for your|test2

動作しますが、私の希望通りには動作しません。テキスト内の「test」と「test2」という単語をすべて検索します。しかし、私は「test」の後にのみ「test2」が来るような、あるパターンのようなテキストブロックを取得したいのです。何かアイデアはありますか?

答え1

sed を使用した簡単なシェル スクリプト。2 番目のケースの行番号のリストを作成し、最初のケースの行番号と比較します。一致するペアを出力します。最初の引数をファイル名として使用します。2 番目と 3 番目の引数を一致するパターンとして受け取るように簡単に拡張できます。findnext.sh として保存し、次のように実行できます。

$ sh findnext.sh testfile

ファイルを 2 回パスするだけなので高速であり、完全に移植可能であるという利点があります。

#!/bin/sh 
# Line numbers matching test1
mt2=$(sed -ne '/test1/=' < $1 | tr '\n' '/')

for l in $(sed -ne '/test/=' < $1); do
    nextline=$(expr $l + 1)
    [ "${mt2#*$nextline/}" != "$mt2" ] && sed -ne $l,${nextline}p <$1
done

答え2

grep -E または egrep を試すことができます。次のように試してください。

#this will show lines that have test or test2
    grep -E "test|test2" file

testとtest2を含む行をtest|test2のように表示したい場合は、次のようにします。

# This will show lines that has test|test2
    grep "test\|test2" file

答え3

awkこれには次のツールが適しているかもしれません:

awk '/test$/, /test2$/' < block-text-lines.txt 

一般的な形式は次のとおりです。

awk '/start-pattern/, /end-pattern/{command}'

ただし、コマンド ブロックはデフォルトで印刷されるため、開始パターンと終了パターンだけで十分です。

チェックアウトman awkまたはGnu Awk ユーザーズガイドのために方法もっと詳しく。

答え4

grep -A 1 "test$" in.txt | grep -B 1 "test2$"

grepマニュアル

-A NUM一致した行の後の末尾のコンテキストの NUM 行を出力します。

-B NUM一致する行の前の先頭のコンテキストの NUM 行を出力します。

このコマンドgrep -Pzo ".*test$\n.*test2$" in.txtも機能しますが、マニュアルには「これは非常に実験的なものであり、grep -P は実装されていない機能について警告する場合があります」と記載されています。

関連情報