grep 또는 awk를 사용하여 시스템 로그에서 특정 필드를 추출하고 싶습니다.

grep 또는 awk를 사용하여 시스템 로그에서 특정 필드를 추출하고 싶습니다.

다음은 제가 작업 중인 시스템 로그의 예입니다. 시스템 로그에서 및 필드를 추출하려고 합니다 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:
  • 다른 그룹을 정의하십시오. 이 그룹은 쉼표가 아닌 문자( account_id; 뒤에 쉼표 [^,]*) 가 0개 이상 일치합니다.
  • 줄 끝까지( .*$) 까지 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

관련 정보