这是我正在处理的系统日志的示例。我正在尝试从系统日志中提取account_id
和字段:version_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
对于每一行这个
- 从行首开始 (
^
) - 匹配 0 个或多个任意字符 (
.*
),直到达到version_apk: '
- 定义一个群(
\(...\)
)。该组匹配 0 个或多个非单引号字符(将结束 version_apk 值的单引号;[^']*
)。 - 再次匹配 0 个或多个任意字符 (
.*
),直到到达account_id:
- 定义另一个组。该组匹配 0 个或多个不是逗号的字符(
account_id
;后面的逗号[^,]*
) - 匹配 0 个或多个字符直至行尾 (
.*$
) - 将整个匹配项替换为第一组的内容、空格和第二组的内容 (
\1 \2
)
这个假设version_apk
总是会出现在之前account_id
。
答案2
将 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