Linux 시스템의 웹 서비스에서 일부 로그가 있습니다. 로그는 다음과 같습니다.
{"log":"[2023-03-09T06:39:10.669Z] \"GET /server/prod?blank=true HTTP/1.1\" 200 - 0 874 1 1 \"-\" \"-\" \"aaad-bbb-ccc-dd-eeeee\" \"example.com:22213\" \"172.16.2.1:10080\"\n","stream":"stdout","time":"2023-03-09T06:39:11.935831787Z"}
보시다시피 큰따옴표가 몇 개 있습니다. 세 번째와 네 번째 큰따옴표 사이, 그리고 11번째와 12번째 큰따옴표 사이에 있는 내용을 인쇄해야 합니다. 이는 내가 다음과 같은 것을 얻고 싶다는 것을 의미합니다.
"GET /server/prod?blank=true HTTP/1.1\" "example.com:22213\"
저는 내용에만 관심이 있어요. 나는 상관하지 "
않는다 \
.
답변1
사용jq
, 키 값을 추출하고 디코딩할 수 있습니다 log
.
$ jq -r .log file
[2023-03-09T06:39:10.669Z] "GET /server/prod?blank=true HTTP/1.1" 200 - 0 874 1 1 "-" "-" "aaad-bbb-ccc-dd-eeeee" "example.com:22213" "172.16.2.1:10080"
이는 본질적으로 공백 문자를 필드 구분 기호로 사용하는 헤더 없는 CSV 레코드이므로 다음과 같은 CSV 인식 도구를 사용할 수 있습니다.밀러( mlr
)는 두 번째 및 12번째 필드를 구문 분석합니다.
$ jq -r .log file | mlr --csv -N --fs space cut -f 2,12
"GET /server/prod?blank=true HTTP/1.1" example.com:22213
더 쉽게 구문 분석하려면 TSV 출력 형식을 사용할 수 있습니다.
$ jq -r .log file | mlr --c2t -N --ifs space cut -f 2,12
GET /server/prod?blank=true HTTP/1.1 example.com:22213
첫 번째 필드에는 더 이상 포함된 구분 기호가 포함되어 있지 않으므로 Miller는 자동으로 따옴표를 제거합니다.
--csv
to( --c2t
함께 사용되는 것과 동일) 및 from to(세트만 해당)에 유의하세요 .--icsv
--otsv
--fs
--ifs
입력하다출력 필드 구분 기호가 아닌 필드 구분 기호). 이 경우 Miller는 TSV와 CSV를 동일하게 처리하므로(필드 구분 기호만 다름)로 변경 --fs space
하면 동일한 효과가 나타납니다.--ifs space --ofs tab
답변2
내 계산에 따르면 네 번째와 다섯 번째 큰따옴표 사이에 텍스트가 필요하고 그 다음에는 열두 번째와 열세 번째 큰따옴표 사이에 텍스트가 필요합니다.
sed -E 's/^([^"]*"){4}([^"]*")([^"]*"){8}([^"]*").*$/"\2 "\3/'
( sed
GNU, 다양한 BSD 또는 Busybox와 같은 확장 정규식을 지원하는 것을 사용하십시오) 또는
sed 's/^\([^"]*"\)\{4\}\([^"]*"\)\([^"]*"\)\{8\}\([^"]*"\).*$/"\2 "\3/'
(아무거나 사용 sed
).
답변3
샘플 awk
스크립트가 작업을 수행합니다. 이는 "
문자를 필드 구분 기호로 사용하므로 첫 번째 필드( $1
)는 첫 번째 필드 앞의 부분입니다 "
.
awk -F\" '{print $5 " " $13}'
gsub()
백슬래시도 제거하려면 스크립트에서 예를 들어 다음을 사용할 수 있습니다.
awk -F\" '{gsub(/\\/, ""); print $5 " " $13}'