ファイル内にはこのようなレコードが何百万件もあります
echo "NEW Cell"
grep "2553,24" out.2A25.20090308.64436.7.HDF.txt.text = 22.58 5.39 82.09 237
echo "NEW Cell"
grep "2555,20" out.2A25.20090308.64436.7.HDF.txt.text = 24.72 5.58 82.05 237
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75 5.62 82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34 5.58 82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2 5.57 82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69 5.62 82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74 5.60 82.30 120
echo "NEW Cell"
grep "2560,24" out.2A25.20090308.64436.7.HDF.txt.text = 19.38 5.54 82.30 170
echo "NEW Cell"
ここで、「新しいセル」を含む行の間にある唯一の行であるという条件で、「grep」を含む行を削除したいと思います。つまり、新しいセルの間に grep の行が 1 つある場合は、この行を削除する必要があります。
これを行う方法?
出力は次のようになります。
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75 5.62 82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34 5.58 82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2 5.57 82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69 5.62 82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74 5.60 82.30 120
答え1
AWK
解決:
awk 'NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }
/NEW Cell/{ f=1; n=NR+2; r=$0; next }
f && n-NR==1 && /^grep /{ gr=$0; next }1' file
/NEW Cell/{ f=1; n=NR+2; r=$0; next }
- ラインに遭遇するとNEW Cell
f=1
= アクティブフラグを設定するf=1
n=NR+2
-n
処理する次の行の最大数を設定します(次の 2 行)r=$0
- ラインをキャプチャするnext
- 次のレコードへジャンプ
f && n-NR==1 && /^grep /
-キーワードn-NR==1
で始まる2行目( によって保証される)に遭遇するとgrep
gr=$0; next
-grep
行をキャプチャし、次の(3番目の)レコードにジャンプする
NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }
- 3番目の重要なラインに遭遇したとき(によって保証されるNR==n
)if (/NEW Cell/) { f=0 }
- 処理済みセクションの3行目に以下が含まれている場合NEW Cell
- 現在の処理をリセットしますf=0
(以前にキャプチャされた行はすべてスキップされます)else print r ORS gr
- それ以外の場合は、以前にキャプチャしたすべての行を印刷します
出力:
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75 5.62 82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34 5.58 82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2 5.57 82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69 5.62 82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74 5.60 82.30 120
答え2
コンパクトなソリューションsed
:
sed '/NEW Cell/!{H;d;};x;/\n.*\n/!d'
行にNEW Cell
実行が含まれていない場合はH
、ホールド スペースに行を追加し、d
その行の処理を停止します。
したがって、以降のコマンドは行にのみ適用されますNEW Cell
。 はx
パターン スペースとホールド スペースを交換するため、行はホールド スペースに配置され、さらに行を追加できます。一方、パターン スペースには最後のNEW Cell
行に追加されたすべてのものが含まれます。 要件は、行間に複数の行があることであるNEW Cell
ため、パターン スペースには少なくとも 2 つの改行が必要です。 そうでない場合は、出力せずに削除します/\n.*\n/!d
。
答え3
初歩的なawk
...
バージョン 1 では、grep
OP の説明に従う行のみが削除されます。
awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
else { f=1; s=$0 } } ! /^echo/ { print; f=0 } \
! /^echo/ && ! /^grep/ { print }' inputfile
バージョン 2 では、単独のgrep
行と、OP のサンプル出力に続く先行する非 grep 行が削除されます。
awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
else { f=1; s=s "\n" $0 } } /^echo/ { s=$0; f=0 } \
! /^echo/ && ! /^grep/ { print }' inputfile
バージョン 2 の読み取り可能な形式...
/^grep/ {
if (found) { # found==true : already encountered first grep line
if (length(save) > 0) {
print save
save=""
}
print
} else {
found=1
save=save "\n" $0 # append the first grep line to saved preceding line
}
}
/^echo/ {
save=$0 # save this line for possible later printing
found=0
}
# print anything else
! /^echo/ && ! /^grep/ { print }
この長い形式は、内容をファイル (例awkfile
) およびに配置することで実行できますawk -f awkfile inputfile
。
答え4
gawk '
/\n.+\n/{
printf("%s%s", RS, $0);
}' RS='echo "NEW Cell"\n' input.txt
説明:
RS='echo "NEW Cell"\n'
- はRS
入力レコードの区切り文字で、デフォルトでは改行です。現在は に変更されているecho "NEW Cell"\n
ため、この文字列のすべての出現が削除され、その間にあるすべての文字がレコード項目になります。/\n.+\n/{
- このパターンに一致するレコードのみ - 改行、1 つ以上の文字、改行。したがって、複数行のレコードにのみ一致し、単一行のレコードは 1 つしかないため一致しません\n
。printf("%s%s", RS, $0);
RS
- 先頭に( )を付けてレコードを出力しますecho "NEW Cell"\n
。
出力
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75 5.62 82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34 5.58 82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2 5.57 82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69 5.62 82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74 5.60 82.30 120