필드가 awk에 없으면 캐리지 리턴을 추가하십시오.

필드가 awk에 없으면 캐리지 리턴을 추가하십시오.

나는 사용하고있다

awk -F'[":]' '$2=="id"{printf("pri,%s,",$5)}$2=="name"{printf("%s,",$5)}$2=="objectId"{printf$4}$2=="polledName"{print$5}' | sed -e 's/, /,/g'

이것이 되었다

  }, {
    "id" : "1",
    "name" : "host1",
    "objectId" : 0001,
    "polledName" : "192.168.1.1"
  }, {
    "id" : "2",
    "name" : "host2",
    "objectId" : 0002,
    "polledName" : "192.168.1.2"
  }, {
    "id" : "3",
    "name" : "host3",
    "objectId" : 0003,
  }, {
    "id" : "4",
    "name" : "host4",
    "objectId" : 0004,
    "polledName" : "192.168.1.3"
  }, {

이것을 입력하세요

pri,1,host1,0001,192.168.1.1
pri,2,host2,0002,192.168.1.2
pri,3,host3,0003,pri,4,host4,0004,192.168.1.3

polledName에 대한 항목이 존재하지 않을 때 현재 줄로 줄 바꿈하는 대신 다음 줄로 이동하도록 이를 수정하는 방법에 대한 아이디어가 있습니다. 즉, $5가 아무것도 반환하지 않으면 개행을 추가하세요.


위의 코드는 awk 스크립트가 gawk -o-읽기 쉽게 인쇄되어 있습니다.

awk -F'[":]' '
    $2 == "id" {
            printf "pri,%s,", $5
    }
    
    $2 == "name" {
            printf "%s,", $5
    }
        
    $2 == "objectId" {
            printf $4
    }
    
    $2 == "polledName" {
            print $5
    }
' | sed -e 's/, /,/g'

답변1

누구에게나하다명령줄에서 JSON 작업을 위한 적절한 도구에 액세스하면 다음을 사용하여 필드를 참조된 CSV 데이터 세트로 추출할 수 있습니다 jq.

$ jq -r '.[] | [ "pri", .id, .name, .objectId, .polledName ] | @csv' file
"pri","1","host1",1,"192.168.1.1"
"pri","2","host2",2,"192.168.1.2"
"pri","3","host3",3,
"pri","4","host4",4,"192.168.1.3"

이는 질문에 표시된 데이터가 최상위 배열의 일부이고 올바른 형식이라고 가정합니다(질문의 세 번째 요소에 잘못된 후행 쉼표가 포함되어 있음).

[
    {"id":"1","name":"host1","objectId":1,"polledName":"192.168.1.1"},
    {"id":"2","name":"host2","objectId":2,"polledName":"192.168.1.2"},
    {"id":"3","name":"host3","objectId":3},
    {"id":"4","name":"host4","objectId":4,"polledName":"192.168.1.3"}
]

따옴표로 묶인 빈 문자열로 바꾸려면아무것도 없다누락된 .polledName값 의 경우 .polledName표현식을 jq로 변경합니다 .polledName // "". null키를 사용할 수 없거나 해당 값이 있는 경우 값 대신 빈 문자열을 사용합니다 null.

탭으로 구분된 값을 얻으려면 출력 연산자 @csv로 변경하세요 .@tsv

이를 수행하기 위해 JSON 인식 도구를 사용하면 JSON으로 인코딩된 데이터가 아닌 디코딩된 문자열을 출력에서 ​​얻을 수 있다는 이점이 있습니다. 또한 포함된 따옴표 등은 자동으로 올바르게 처리되며 JSON 입력이 한 줄에 있는지 또는 다른 특별한 방식으로 형식이 지정되는지는 중요하지 않습니다.

답변2

꼭 사용해야 한다면 awkpolledName에 대한 변수를 설정/설정 해제하세요.

 awk -F'[":]' '$2 == "id" {if(lf) print "" ; printf("pri,%s,",$5); lf=1;}
               $2 == "name" {printf("%s,",$5)}
               $2 == "objectId" {gsub(" ","",$4); printf "%s", $4}
               $2 == "polledName" {print $5; lf=0; }
               END {if(lf) print "" ;}' 

이것은 기본적으로 약간 확장된 코드입니다. 제가 추가한 내용은 다음과 같습니다.

  • "id"가 있는 줄은 if(lf) print "" ;새 줄을 인쇄합니다( lf0이 아닌 경우) lf=1.lf
  • "polledName"이 포함된 선택적 행: lf=0;행이 발견되면 lf를 지웁니다.
  • 주석별로 사용됩니다 print ""( print인수 없이는 현재/마지막 줄이 인쇄됩니다).
  • $4에 추가된 gsub(" ","",$4);스트립 공백 (구분 기호가 공백이 아니기 때문에 공백이 보존됨)

이는 awkjson(또는 xml) 파일을 구문 분석하기에는 좋지 않은 솔루션입니다.

이 json 파일을 생성한 프로그램에 따라 다르며 특히 폐쇄된 서버나 장치에 있는 경우 필드 순서가 변경될 수 있습니다.

답변3

줄 순서가 다르거나 다르거나 추가 줄이 손실될 수 있더라도 awk를 사용하세요.

$ awk -F'(^ *")|("?,?$)|(" : "?)' -v OFS=',' '
    /}, {/ {
        if ( NR>1 ) {
            print "pri", f["id"], f["name"], f["objectId"], f["polledName"]
        }
        delete f
        next
    }
    { f[$2] = $3 }
' file
pri,1,host1,0001,192.168.1.1
pri,2,host2,0002,192.168.1.2
pri,3,host3,0003,
pri,4,host4,0004,192.168.1.3

위의 작동 방식은 행을 읽을 때마다 f[]각 레이블(예: objectId)을 동일한 행의 관련 값(예: )에 매핑한 다음 이를 각 청크의 끝(즉, 표시될 때)에 인쇄하는 배열을 만드는 것입니다. ) 배열의 내용입니다.002tag : value}, {

이와 같은 태그 값의 배열을 생성하는 것은 값을 인쇄하는 것보다 이런 종류의 문제를 해결하는 더 나은 일반적인 방법입니다. 왜냐하면 이는 입력의 태그 순서와 무관하기 때문입니다. 출력하고 배열 값의 저장소를 사용하여 조건을 테스트하고 현재 인쇄 블록에서 조치를 취할 수 있습니다.

if ( f["objectId"] > 27 ) print "The objectId is too big for name", f["name"]

if ( !("polledName" in f) ) print "polledName missing for ID", f["id"]

if ( f["objectId"] ~ /7/) && (f["id"] !~ /7/) ) {
    printf "objectId %s vs id %s mismatch\n", f["objectId"], f["id"]
}

또는 귀하가 관심을 가질 만한 실제 [조합] 조건.

또는 각 블록의 행 순서가 모든 블록에서 일관되게 보장되는 경우 예에 표시된 대로 다중 문자 RS에 GNU awk를 사용할 수 있습니다.

$ awk -v RS='}, {\n' -F'("?,?\n)|(" : "?)' -v OFS=',' '
    NR>1 { print "pri", $2, $4, $6, $8 }
' file
pri,1,host1,0001,192.168.1.1
pri,2,host2,0002,192.168.1.2
pri,3,host3,0003,
pri,4,host4,0004,192.168.1.3

printf $4코드 등의 경우 - printf input_data입력 데이터에 printf 형식 문자가 포함되어 있으면 실패하므로 절대 이 작업을 수행 하지 마십시오 . printf "%s", input_data예를 들어 .printf "%s", $4

또한 awk를 사용하면 sed가 필요하지 않으므로 이 작업을 수행하는 경우 잘못된 작업을 수행하는 것입니다.

관련 정보