まず最初に、入力データにタイプミスがあるようです。10000018
必要な出力を得るには、最初に10000019
.
それが修正されたら、ソートされたファイルを次のawk
スクリプトに渡すことで、目的の出力を取得できます。
NR==1 {
first = $0;
last = $0;
prev = $0;
count = 1;
next;
}
$0 == prev+1 {
last = $0;
prev = $0;
count++;
next;
}
{
print first","last","count;
first = $0;
last = $0;
prev = $0;
count = 1;
}
END {
if (count > 0) {
print first","last","count
}
}
そのスクリプトdata.awk
を呼び出してデータを に配置するdata.in
と、結果は次のようになります。
pax> sort data.in | awk -f data.awk
10000001,10000006,6
10000008,10000011,4
10000013,10000019,7
10000021,10000021,1
10000023,10000024,2
10000026,10000030,5
awk
スクリプトの仕組みについて詳しく説明します。最初の入力行についてはNR == 1
、現在の値をfirst
、last
およびprev
(シーケンスの開始、シーケンスの終了、およびシーケンスを監視するための前の行) に格納するだけです。また、現在のカウントを に設定し1
、2 番目の行を処理するために戻ります。ライン。
後続のすべての行で、$0 == prev+1
現在の行が前の行よりも 1 つ多い場合、2 番目のセクションが起動します。その場合、last
とのprev
値とインクリメントを更新するだけcount
で、先頭に戻って次の行を処理します。
したがって、3 番目のセクションは、最初の 2 つのセクションでキャプチャされないすべてのケースに対して発生します。これは、行が 1 と前の行ではない入力ファイルの最初のレコード以外のレコードです。つまり、新しいシーケンスを開始するとき。最初に最新のシーケンスの詳細を出力し、次に最初のセクションで行ったことを複製します。
このEND
セクションは、最終シーケンスの詳細を出力するために必要なすべての行が処理された後に起動します。count
がゼロより大きい場合にのみ出力されることに注意してください。count
がゼロの場合、ファイルは空であり、シーケンスはまったくありませんでした。
いくつかの追加条件、行の結合、およびセクションが順番に処理されるという事実に依存する、わずかに短いバリアントもあります。
NR > 1 && $0 == prev+1 {
last = $0; prev = $0; count++;
next;
}
{
if (NR != 1) { print first","last","count; }
first = $0; last = $0; prev = $0; count = 1;
}
END {
if (count > 0) { print first","last","count }
}
そしてもちろん、非常に短い (そしてはるかに読みにくい) コマンド ライン バリアント:
pax> sort data.in | awk 'NR>1&&$0==pr+1{ls=$0;pr=$0;ct++;next}{if(NR!=1){print fr","ls","ct}fr=$0;ls=$0;pr=$0;ct=1}END{if(ct>0){print fr","ls","ct}}'
10000001,10000006,6
10000008,10000011,4
10000013,10000019,7
10000021,10000021,1
10000023,10000024,2
10000026,10000030,5