Here's an example of syslogs that I'm working on. I'm trying to extract the account_id and version_apk fields from the syslogs:

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': '', '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': '', '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})

I tried using:

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

and the same for account_id as well but somehow the count of both differs.

I also tried using awk, but from the examples I saw the variables can be called out using $1, $2 or $35 (only with positions but not names).

The output i desire looks like this:

2.3.7   2417963

Which are nothing but version_apk and account_id for every syslog

Any better approach that I can prefer?


Something like this with sed might help:

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

For each line this

  • starts at the beginning of the line (^)
  • matches 0 or more of any character (.*) until it gets to version_apk: '
  • defines a group (\(...\)). That group matches 0 or more characters that are not a single quote (the single quote that would end the version_apk value; [^']*).
  • matches 0 or more of any character again (.*) until it gets to account_id:
  • defines another group. That group matches 0 or more characters that are not a comma (the comma after the account_id; [^,]*)
  • matches 0 or more characters all the way to the end of the line (.*$)
  • Replaces that entire match with the content of the first group, a space, and the content of the second group (\1 \2)

This assume that version_apk will always come before account_id.

| improve this answer | |

WIith GNU awk for the 3rd arg to match() and 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
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.