次のログファイルがありますが、3回目の試みで正常にログインしたユーザーの名前を印刷したいと思います。
cat login.log
user1:failed
user2:failed
user3:success
user1:failed
user2:failed
user4:success
user5:failed
user2:success
user3:failed
user6:success
user1:success
user3:success
user4:success
user4:success
user5:failed
user5:failed
user1:success
user2:failed
予想される出力は次のとおりです。
user1
user2
答え1
努力する
awk -F: '/failed/ { f[$1]++;} /success/ && f[$1]==2 { print ; f[$1]=0 ; }'
どこ
-F:
:
区切り文字として使用/failed/ { f[$1]++;}
ユーザーログイン失敗回数の計算/success/ && f[$1]==2 { print $1; f[$1]=0 ; }
条件に応じて結果を印刷します。
コメントに従って特別な名前がある場合(読みやすくするために改行)
awk -F: '$2 == "failed" { f[$1]++;}
$2 == "success" && f[$1]==2 { print ; f[$1]=0 ; }'
答え2
単純なbashのみの解決策:行を繰り返し、失敗するたびにカウンターを増やし、成功するたびにそのカウンターの値を確認し、必要な値と一致するといくつかの出力を生成します。sort -u
最後のボーナスは、すべての出現ではなく、一致するユーザーのみを出力することです。可能な改善方法は、成功時にカウンタをゼロにリセットすることです。ただし、これを行う方法を直接理解できるはずです。
$ unset FAILURES # In case you've already tried inthis shell
$ declare -A FAILURES
$ while IFS=: read USERNAME STATUS ; do [ "$STATUS" == "failed" ] && (( FAILURES[$USERNAME] += 1)); [ "$STATUS" == "success" -a "0${FAILURES[$USERNAME]}" -eq 2 ] && echo $USERNAME because status is $STATUS and failures is ${FAILURES[$USERNAME]}; done < login.log | sort -u
user1 because status is success and failures is 2
user2 because status is success and failures is 2
$
答え3
誰がログインしたかを追跡し、この極端なケースと一致しないようにします。
joe:success
joe:failed
joe:failed
joe:success
awk -F: '
$2 == "failed" {fail[$1]++}
$2 == "success" && !loggedin[$1] {
if (fail[$1] == 2) print $1
loggedin[$1] = 1
}
' login.log
以前にログインしたかどうかにかかわらず、2回連続失敗した後にログインする人に興味がなければ。この場合、必要なものは次のとおりです。
awk -F: '
$2 == "failed" {fail[$1]++}
$2 == "success" {
if (fail[$1] == 2) print $1
fail[$1] = 0
}
' login.log