私のLinuxシステムには次のファイルがあります。
May 6 19:12:03 sys-login: user1 172.16.2.102 Login /data/netlogon 13473
May 6 19:15:26 sys-login: user2 172.16.2.107 Login /data/netlogon 14195
May 6 19:28:37 sys-logout: user1 172.16.2.102 Logout /data/netlogon 13473
May 6 19:33:28 sys-logout: user2 172.16.2.107 Logout /data/netlogon 14195
May 8 07:58:50 sys-login: user3 172.16.6.128 Login /data/netlogon 13272
May 8 07:58:50 sys-logout: user3 172.16.6.128 Logout /data/netlogon 13272
各ユーザーがログインしてログアウトするのにかかる時間(分)を計算しようとしています。ユーザーごとに1回のログイン/ログアウトのみが可能で、すべてのユーザーのレポートを一度に生成したいと思います。
私が試したこと:
まず、ユーザーを抽出しようとしています。
users=$(awk -v RS=" " '/login/{getline;print $0}' data)
ユーザー(ログイン)を返し、ログインした時間を抽出しようとしましたが、現在停止しています。どんな助けでも大変感謝します!
編集:ユーザーと日付に以下を実行させることができました。
users=$(grep -o 'user[0-9]' data)
dates=$(grep -o '[0-2][0-9]:[0-5][0-9]:[0-5][0-9]' data)
完全な解決策を見つけたら、ここで共有します。
ベストアンサー1
このサイトは「スクリプトサービスではありません」;)、これは非常に良い小さな練習なので、次のプログラムを考えてみましょうawk
。ファイルとして保存できますcalc_logtime.awk
。
#!/usr/bin/awk -f
/sys-log[^:]+:.*Log/ {
user=$5
cmd=sprintf("date -d \"%s %d %s\" \"+%%s\"",$1,$2,$3)
cmd|getline tst
close(cmd)
if ($7=="Login") {
login[user]=tst
}
else if ($7=="Logout") {
logtime[user]+=(tst-login[user])
login[user]=0
}
}
END {
for (u in logtime) {
minutes=logtime[u]/60
printf("%s\t%.1f min\n",u,minutes)
}
}
date
これは、GNUコマンド(GNU / Linuxシステムの標準ツールバーの一部)の使用とログファイルで指定された時間形式によって異なります。また、これには多くのセキュリティチェックは含まれていませんが、必要に応じて修正する方法を知っておく必要があります。
- 次を含む行を探します。両方
sys-log
Log
何か他のものがある場合は、選択性を高めるために始めと終わりに近い文字列です。前述のように、これは非常に基本的なテストですが、もう一度具体的にする方法を学ぶことができます。 - ユーザーは、行からスペースで区切られた5番目のフィールドに抽出されます。
- ジョブは、行のスペースで区切られた7番目のフィールドに抽出されます。
date
呼び出しを作成しsprintf
てジョブをシェルに委任することで、ジョブのタイムスタンプが「エポック以降の秒」に変換されます。- ジョブがある場合、タイムスタンプはユーザー名を「配列インデックス」として配列
Login
に保存されます。login
- ジョブがある場合、
Logout
期間が計算され、logtime
現在まですべてのユーザーの合計ログイン時間を含む配列に追加されます。 - ファイルの終わりですべての「配列インデックス」を繰り返し、
logtime
単純な除算を使用してログ時間を秒から分に変換することによってレポートが生成されます。
電話でお問い合わせください。
awk -f calc_logtime.awk logfile.dat