例:
a43
test1
abc
cvb
bnm
test2
kfo
Test1とtest2の間のすべての行が必要です。この場合、通常のgrepは機能しません。何か提案はありますか?
test1
からtest2
に印刷(トリガー行を含む)
awk '/test1/{f=1} /test2/{f=0;print} f'
awk '/test1/{f=1} f; /test2/{f=0}'
awk '/test1/,/test2/'
test1
abc
cvb
bnm
test2
test1
からtest2
までのデータを印刷します(トリガー行は除外されます)
awk '/test1/{f=1;next} /test2/{f=0} f'
awk '/test2/{f=0} f; /test1/{f=1}'
abc
cvb
bnm
sed
を使用できます:
sed -n '/test1/,/test2/p' filename
test1
およびtest2
を含む行を除外するには、次のように言います。
sed -n '/test1/,/test2/{/test1/b;/test2/b;p}' filename
Grepのみを使用できる場合:
grep -A100000 test1 file.txt | grep -B100000 test2 > new.txt
grep -A
に続いて、一致する文字列の後の行を取得し、grep -B
が一致する文字列の前の行を取得します。数値(この場合は100000)は、前後のすべての行を含めるのに十分な大きさでなければなりません。
Test1とtest2を含めたくない場合は、grep -v
で後で削除できます。これにより、一致する行を除くすべてが出力されます。
egrep -v "test1|test2" new.txt > newer.txt
またはすべてを1行で:
grep -A100000 test1 file.txt | grep -B100000 test2 | egrep -v "test1|test2" > new.txt
はい、通常のgrepはこれを行いません。ただし、-P
パラメーターを指定したgrepがこのジョブを実行します。
$ grep -ozP '(?s)test1\n\K.*?(?=\ntest2)' file
abc
cvb
bnm
\K
は、前に一致した文字を最後の印刷から破棄し、肯定的な先読み(?=\ntest2)
は、一致の後に\n
改行文字、次にtest2
文字列が続く必要があることを表明します。
上記のPratPorによる答え:
cat test.txt | grep -A10 test1 | grep -B10 test2
クールですが、ファイルの長さがわからない場合:
cat test.txt | grep -A1000 test1 | grep -B1000 test2
確定的ではありませんが、それほど悪くはありません。誰もがより良い(より決定論的)ですか?
このようなこともできます。このファイルtest.txt
にコンテンツが含まれているとしましょう:
a43
test1
abc
cvb
bnm
test2
kfo
できるよ
cat test.txt | grep -A10 test1 | grep -B10 test2
ここで、-A<n>
は、ファイル内の一致の後にn
行を取得し、-B<n>
は一致の前にn
行を取得します。 n > number of expected lines between test1 and test2
であることを確認する必要があります。または、EOFに達するのに十分な大きさにすることができます。
結果:
test1
abc
cvb
bnm
test2
次のスクリプトは、このプロセスをまとめています。詳細 この似たようなStackOverflowの投稿
function show_help()
{
HELP=$(doMain $0 HELP)
echo "$HELP"
exit;
}
function doMain()
{
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$1" ]
then
show_help
fi
if [ -z "$2" ]
then
show_help
fi
FILENAME=$1
if [ ! -f $FILENAME ]; then
echo "File not found: $FILENAME"
exit;
fi
if [ -z "$3" ]
then
START_TAG=$2_START
END_TAG=$2_END
else
START_TAG=$2
END_TAG=$3
fi
CMD="cat $FILENAME | awk '/$START_TAG/{f=1;next} /$END_TAG/{f=0} f'"
eval $CMD
}
function help_txt()
{
HELP_START
get_text.sh: extracts lines in a file between two tags
usage: FILENAME {TAG_PREFIX|START_TAG} {END_TAG}
examples:
get_text.sh 1.txt AA => extracts lines in file 1.txt between AA_START and AA_END
get_text.sh 1.txt AA BB => extracts lines in file 1.txt between AA and BB
HELP_END
}
doMain $*