grepまたはawkを使用してシステムログから特定のフィールドを抽出したいと思います。

grepまたはawkを使用してシステムログから特定のフィールドを抽出したいと思います。

以下は、私が作業しているシステムログの例です。システムログからフィールドを抽出しようとしていますaccount_idversion_apk

Sep 16 06:59:16 as09 janus-server[as09][21840]: INFO: janus.application.application: 120:  audha6xnTESMSvpgr5n31Q== R: /rpc/v1/authentication/login({'api_key': 'f6ZO7j11myA8PA3M', 'encoded': True, 'password': 'ZGV2YTEyMzQ=\n', 'login_context': {'channel': 'CR_TN_2017', 'current_location': 'Anthiyur - Vellithiruppur Rd, Vellithiruppur, Tamil Nadu 638314, India', 'device_id': 'abbbecfc99323739', 'geolocation_status_flag': 'None', 'ip_address': '157.49.238.159', 'latitude': '11.6164226', 'long_session': False, 'longitude': '77.6226461', 'mac_address': 'None', 'platform': 'mobile_native_apk', 'postal_code': '638314', 'user_agent': 'Dalvik/2.1.0 (Linux; U; Android 10; Redmi 8 MIUI/V11.0.1.0.QCNINXM)', 'version_apk': '2.3.7'}, 'username': '8903170787'}) => result({'session_id': 'bdd6d9c2469c43e2a0f28542485a7c5d', 'account_id': 2417963, 'username': 'esumk', 'site_code': 'FNIRNCZ', 'destroyed_other_sessions': True, 'forbidden': False, 'previous_login_time': 1600190099, 'device_type': 'mobile_native_apk', 'mac_address': 'None', 'ip_address': '157.49.238.159', 'current_location_latitude': '11.6164226', 'current_location_longitude': '77.6226461', '_caller_api_key': 'f6ZO7j11myA8PA3M', '_api_key': 'benga4eavoh1Ahn2', '_event': 'login', 'show_kyc_popup': False, 'kyc_bonus_popup_message': None, 'kyc_bonus_amount': {'Bonus_INR': 0}, 'front_key': 'paid_android_app', 'camp': {'eligible_status': False}, 'ask_geolocation': False})

私は以下を使用しようとしています:

grep 'login_context' | grep  "'platform': 'mobile_native_apk'" | grep "R."| grep "result" | grep -Po '(?<=version_apk.:)[^,}]+'

同じaccount_idですが、両方を計算する方法は異なります。

私は試しましたが、awk例では$ 1、$ 2、または$ 35(名前以外の場所のみ)を使用して変数を呼び出すことができます。

私が望む出力は次のとおりです。

2.3.7   2417963

システムログごとに version_apk および account_id 以外

私が選択できるより良いアプローチはありますか?

答え1

次のようなものがsed役に立ちます。

$ sed "s/^.*version_apk': '\([^']*\).*account_id': \([^,]*\).*$/\1 \2/" syslog
2.3.7 2417963

各行ごとに

  • 行の先頭から始める(^
  • 次まで、ゼロ個以上のランダム文字(.*)と一致します。version_apk: '
  • グループ(\(...\))を定義します。このグループは、一重引用符ではなく、ゼロ個以上の文字(version_apk値を終了する一重引用符; [^']*)と一致します。
  • .*到達するまで、ゼロ個以上の任意の文字()を再一致させます。account_id:
  • 別のグループを定義します。このグループは、非カンマ文字(account_id;の後にカンマ[^,]*)がゼロ個以上一致します。
  • 行末まで( .*$)まで0個以上の文字マッチ
  • 完全一致を最初のグループの内容、スペース、および2番目のグループの内容(\1 \2)で置き換えます。

この仮定はversion_apk常に前に来ますaccount_id

答え2

3番目の引数をGNU awkに設定match()し、次の操作を行いますgensub()

$ cat tst.awk
/'login_context'/ && /'platform': 'mobile_native_apk'/ && /R./ && /result/ {
    delete f
    while ( match($0,/'([^']+)': ('[^']+'|[0-9]+)/,a) ) {
        f[a[1]] = gensub(/'/,"","g",a[2])
        $0 = substr($0,RSTART+RLENGTH)
    }
    print f["version_apk"], f["account_id"]
}

$ awk -f tst.awk file
2.3.7 2417963

関連情報