
いくつかの行を含むテキストがあります。そのため、いくつかの行を 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 は実装されていない機能について警告する場合があります」と記載されています。