シェルスクリプトは連続した日数のみを計算します。

シェルスクリプトは連続した日数のみを計算します。

これをどうするかを知りたいです。

私の出力の例は次のとおりです。

Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH

今私がしたいのは数字を数えるだけです。続けてBLAH仕事なので、上の例では連続して現れるので、3回現れると言うべきです。

bash、awk、およびsedを使用できます。

答え1

AWKでは:

{
    sub(",", "", $0);  # kill first comma, thanks Thomas
    cmd="date -d \""$1" "$2" "$3" "$4" "$5" 1 day ago\" \"+%b %e\"";
    cmd|getline dt;
    close(cmd);
    if (dt==prev && blah==substr($0, index($0, $6))) { times = times + 1 }
    else { print times" "line; times = 1 };
    prev=$2" "$3;
    blah=substr($0, index($0,$6));
    line=$0;
}
END { print times" "line }

次のファイルにこの入力があるとしますblah.log

Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH

awkスクリプトでは、consecutive.awk次のことができます。

$ awk -f consecutive.awk blah.log

3 Tue Aug 23 2016 04:22:11 BLAH
1 Thu Aug 25 2016 05:00:00 BLAH

連続した日数を追加の列として指定し、最後の日付を印刷します。出力から日付を削除するには(両方の場所に表示されます)print times" "lineに変更します。print times" "blah

仕組み:

  • Glenn jackmanのおかげで、dateコマンドを実行して現在の行の昨日を取得します。
  • 前の行に保存された日付と比較
  • カウンターの増加または印刷
  • 次の実行のために現在の行のデータを保存します。

メモ:

  • 見苦しいです(すべてのAWKコードがそうであるように、克服してください)。
  • を使用するので、すべての間隔(最大1年)でうまく機能しますが、dateタイムゾーンを無視します。
  • BLAHは、異なるラインで異なる可能性があることを考慮し、BLAH発生を他のBLAH発生とのみ一致させる。ファイルが正しくソートされていない場合sort -t , -k 2
  • BLAHのさまざまな値を説明する必要がある場合は、GNU awkが必要です(お寄せいただきありがとうございますsubstr)。それ以外の場合は呼び出しを終了でき、substrスクリプトはすべてのposix awkで実行されます。

答え2

思ったより時間がかかりましたが、以下のスクリプトはそのタスクを実行します。

#!/bin/bash
str=" Sun Aug 21 2016 03:00:00, BLAH Mon Aug 22 2016 03:54:00, BLAH"
str+=" Tue Aug 23 2016 04:22:11, BLAH Thu Aug 25 2016 05:00:00, BLAH"
IFS='H' read -r -a inputArray <<< "$str"
days=(SunMon MonTue TueWed WedThu ThuFri FriSat SatSun)
count=1
found=0
lastOne=""
finalCount=0
for entry in "${inputArray[@]}"; do
   thisOne="${entry:1:3}"
   test="$lastOne$thisOne"
   for pair in "${days[@]}"; do
      if [ "$test" == "$pair" ]; then
         ((++count, ++found))
      fi
   done
   if [ ! $found ]; then count=1; else found=0; fi
   if [ $count -gt $finalCount ]; then
      finalCount=$count
   fi
   lastOne=$thisOne
done
echo "There were $finalCount BLAHs in a row."

関連情報