awk 그룹화 및 "감소"

awk 그룹화 및 "감소"

다음과 같은 데이터가 있다고 가정해 보겠습니다.

table_name id
table_name col_1
table_name col_2
another_table_name id
another_table_name col_1

첫 번째 열을 사용하여 그룹화 awk하고 두 번째 열을 쉼표로 구분된 목록으로 줄이려면 어떻게 해야 합니까? 예제에 따르면 출력은 다음과 같아야 합니다.

table_name id,col_1,col_2
another_table_name id,col_1

여기서 아이디어는 두 번째 열을 사용하여 jq첫 번째 열(키)의 데이터를 기반으로 JSON 배열(값)을 구성할 수 있다는 것입니다.

{"table_name": ["id", "col_1", "col_2"]}
{"another_table_name": ["id", "col_1"]}

grrouby/"reduce" 단계를 제외하고는 모든 것이 잘 작동합니다. 도움을 주시면 대단히 감사하겠습니다!

답변1

JSON 구조를 생성하는 가장 간단한 옵션은 다음을 사용하는 것입니다.jo유틸리티:

$ sed 's/[[:blank:]]\{1,\}/[]=/' file | jo -p
{
   "table_name": [
      "id",
      "col_1",
      "col_2"
   ],
   "another_table_name": [
      "id",
      "col_1"
   ]
}

sed스크립트 는 첫 번째 공백 또는 탭 집합을 . 샘플 데이터를 기반으로 하면 다음과 같은 결과가 나옵니다.jo[]=

table_name[]=id
table_name[]=col_1
table_name[]=col_2
another_table_name[]=id
another_table_name[]=col_1

그런 다음 jo유틸리티는 데이터를 올바르게 인코딩하고 JSON 문서를 생성하는 일을 담당합니다. 컴팩트한 출력을 원할 경우 -p옵션을 제거하세요.jo


이전 답변은 jq대안을 사용하지만 JSON 인코딩이 필요한 데이터를 처리하지 않습니다.

데이터에 특수 JSON 인코딩이 필요하지 않다고 가정합니다.

jq -n "$(awk '{ printf ".\"%s\" += [\"%s\"] |\n", $1, $2 } END { print "." }' file)"

또는

awk '{ printf ".\"%s\" += [\"%s\"] |\n", $1, $2 } END { print "." }' file |
jq -n -f /dev/stdin

awk이는 배열을 작성하는 표현식을 작성 하는 데 사용됩니다 jq. 주어진 예제 데이터에 대해 jq표현식은 다음과 같습니다.

."table_name" += ["id"] |
."table_name" += ["col_1"] |
."table_name" += ["col_2"] |
."another_table_name" += ["id"] |
."another_table_name" += ["col_1"] |
.

에 의해 평가되면 jqJSON 문서가 생성됩니다.

{
  "table_name": [
    "id",
    "col_1",
    "col_2"
  ],
  "another_table_name": [
    "id",
    "col_1"
  ]
}

-c컴팩트 출력 옵션이 추가되었습니다 jq.


sed대신 사용하십시오 awk:

sed -e 's/\([^[:blank:]]*\)[[:blank:]]*\(.*\)/."\1" += ["\2"] |/' \
    -e '$ s/$/./' file |
jq -n -f /dev/stdin

답변2

기본 아이디어는 이전 줄의 첫 번째 필드를 기억하고, 같으면 쉼표를 인쇄하고, 두 번째 필드를 인쇄하고, 그렇지 않으면 첫 번째와 두 번째 필드를 인쇄하는 것입니다. 그런 다음 일부 극단적인 경우를 처리합니다.

awk '$1 == saved { printf(",%s", $2); next ; }
     neednl { print ""; }
     { saved=$1 ; neednl=1 ;printf("%s %s",$1,$2) ; }
     END { if (neednl) { print "" ; }}'

관련 정보