awk Сгруппировать по и «Уменьшить»

Под Fedora 30 (Gnome 3.30, X11 ), перезагрузка Gnome Shell, кажется, работает для меня:

  1. Запустить быстрый запуск с помощью<Alt> + <F2>

  2. Введите r, затем<Enter>

  3. Дождаться перезагрузки оболочки

Каким-то образом это даже заставляет работать некоторые уже запущенные программы, что для меня не имеет смысла...

1
25.01.2021, 11:54
2 ответа

Самый простой способ создать структуру 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
1
18.03.2021, 22:34

Основная идея состоит в том, чтобы запомнить первое поле из предыдущей строки и, если оно совпадает, вывести запятую и второе поле, в противном случае вывести первое и второе поля. Затем обработайте некоторые граничные случаи

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

Теги

Похожие вопросы