Awk

awk 分組 & “減少”

  • January 25, 2021

假設我有如下數據:

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"]}

除了 grouby /“減少”步驟外,一切正常;非常感謝任何幫助!

創建 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"] |
.

當由 評估時jq,這將創建 JSON 文件

{
 "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

引用自:https://unix.stackexchange.com/questions/630847