3

次のログファイルを考慮して、

FSDFFDSFFDSFDS VCXVCXVCX 3343022340 IT_ON FDSFR0W3EV VXDF03
DDSDS232323SD DSADFSDA SDA32323 SDADSDQ SDAFDSADS SDA DSADSE3QZCD
DDSDS232323SD DSADFSDA SDA32323 SDADSDQ SDAFDSADS SDA DSADSE3QZCD
DDSDSDEERWREF FSFDSDFFDS  SDA32323 SDADSDQ SDAFDSADS SDA DSADSE3Q
DDSDS232323SD DSADFSDA SDA32323 SDADSDQ SDAFDSADSDA 
DSADSE3QZCD FFDSFDAREDFS 23FDSFDDS  IT_ON FDSFR0W3EV VXDF03ETRRT
FFDSFDAREDFS 23FDSFDDSFK 3343022340 IT_OFF FDSFR0W3EV VXDF03ETRRT
DDSDSDEERWREF FSFDSDFFDS  SDA32323 SDADSDQ SDAFDSADS SDA DSADSE3QZCD
DDSDS232323SD DSADFSDA SDA32323 SDADSDQ SDAFDSADS SDA DSADSE3QZCD
FFDSFDAREDFS 23FDSFDDSFK 3343022340 IT_ON FDSFR0W3EV VXDF03ETRRT
FFDSFDAREDFS 23FDSFDDSFK 3343022340 IT_OFF FDSFR0W3EV VXDF03ETRRF
DDSDSDEERWREF FSFDSDFFDS  SDA32323 SDADSDQ SDAFDSADS SDA DSADSE3QZCD
DDSDS232323SD DSADFSDA SDA32323 SDADSDQ SDAFDSADS SDA DSADSE3QZCD
FFDSFDAREDFS 23FDSFDDSFK 3343022340 IT_ON FDSFR0W3EV VXDF03ETRRT
FFDSFDAREDFS 23FDSFDDSFK 3343022340 IT_OFF FDSFR0W3EV VXDF03ETRR
FFDSFDAREDFS 23FDSFDDSFK 3343022340 IT_OFF FDSFR0W3EV VXDF03ETRR

IT_ONからIT_OFFへの遷移とIT_OFFからIT_ONへの遷移がいくつ発生するかを数える必要があります。

IT_ON to IT_OFF : 3
IT_OFF to IT_ON : 2

IFステートメントで*grep"IT_ON"*と*grep"IT_OFF" *を使用しようとしていますが、少し複雑です。何か助けはありますか?

4

6 に答える 6

1
awk '/IT_ON/ {on = 1; if (off) {on_to_off++}; off = 0} /IT_OFF/ {off = 1; if (on) {off_to_on++}; on = 0} END {print "IT_ON to IT_OFF :", on_to_off; print "IT_OFF to IT_ON :", off_to_on}' inputfile

複数の行に分割:

awk '
    /IT_ON/ {
        on = 1; 
        if (off) {
            on_to_off++
        }; 
        off = 0
    } 
    /IT_OFF/ {
        off = 1; 
        if (on) {
            off_to_on++
        }; 
        on = 0
    } 
    END {
        print "IT_ON to IT_OFF :", on_to_off; 
        print "IT_OFF to IT_ON :", off_to_on
    }' inputfile

ID ごとの遷移を追跡するために使用する必要がある ID がある場合は、配列で同じ手法を使用できます。また、フラグを使用して、最初の ON がオフからオンへの遷移としてカウントされるように、最初に表示されたときに ON 状態を設定する必要がある場合もあります。

于 2012-07-10T11:06:21.597 に答える
1

Here is another approach:

 grep -Po "IT_(ON|OFF)" inputFile \
 | uniq | paste - - \
 | awk 'NR==1 && NF==2{print;f=1}END{if(f)printf "%3d\t%3d\n", NR,NR-1}'

Output format:

IT_ON   IT_OFF
  3       2
于 2012-07-10T11:25:58.940 に答える
1

data.logデータファイルの名前を次のように仮定します。

grep -Eo 'IT_(ON|OFF)' data.log | uniq | tail -n +2 |sort |uniq -c

出力:

3 IT_OFF
2 IT_ON

注釈付き:

grep -Eo 'IT_(ON|OFF)' data.log $(: -E for extended regex, -o to only print matching part ) \
  | uniq                        $(: deduplicate adjacent items ) \
  | tail -n +2                  $(: drop the first line )        \
  | sort | uniq -c              $(: sort , then give a count for each unique item )
于 2012-07-10T15:52:36.070 に答える
0

あなたが求めることを行うbashのシェルスクリプトは次のとおりです。

#!/bin/bash

testfile="test.txt"

uniques=$(command grep -o IT_O. $testfile | uniq)
count=$(echo "$uniques" | paste - - | grep -c "IT_O.[[:space:]]IT_O.")

if [[ ${uniques:0:5} = "IT_ON" ]]; then
    echo "IT_ON  -> IT_OFF: $count"
    echo "IT_OFF -> IT_ON : $(($count-1))"
else
    echo "IT_ON  -> IT_OFF: $(($count-1))"
    echo "IT_OFF -> IT_ON : $count"
fi

残念ながら、テストにあまり時間を割くことができませんでした。いくつかの試行を実行して、ユース ケースに対して十分に堅牢であるかどうかを確認してください。

于 2012-07-10T12:52:55.800 に答える
0

あなたが望むものとは異なりますが、うまくいくかもしれません:

sed -n 's/.*\(IT_ON\|IT_OFF\).*/\1/p' input | uniq > input.tmp
grep $(head -1 input.tmp) input.tmp | uniq -c
expr $(grep $(head -2 input.tmp | tail -1) input.tmp | wc -l) - 1
rm input.tmp
于 2012-07-10T11:24:12.757 に答える
0

awk で:

/IT_ON/        { on=1; }
on && /IT_OFF/ { offs++; on=0; off=1; }
off && /IT_ON/ { ons++; off=0; on=1; }
END {
  printf("ON to OFF: %d\nOFF to ON: %d\n", offs, ons);
}

戻り値:

ON to OFF: 3
OFF to ON: 2

シェルを含む任意の言語で同じロジックを実装できますが、これが最もクリーンに思えます。

于 2012-07-10T14:39:47.483 に答える