0Pricing
Linux Command Line & Bash Scripting Mastery · Lekcja

Przekształcanie i tworzenie obiektów JSON za pomocą jq

Przekształcaj dane za pomocą map, to_entries i konstruowania obiektów, aby tworzyć nowe ładunki JSON.

Przekształcanie i tworzenie obiektów JSON za pomocą jq to bezpłatna lekcja Linux Command Line & Bash Scripting Mastery na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Linux Command Line & Bash Scripting Mastery, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Linux Command Line & Bash Scripting Mastery zawiera 4 lekcji w sumie.

Po co przekształcać JSON?

Surowy JSON z API lub plików dziennika rzadko ma dokładnie taką strukturę, jakiej Państwo potrzebują. Mogą Państwo otrzymać duży obiekt, z którego potrzebne są tylko konkretne pola, albo chcieć zmienić nazwy kluczy, spłaszczyć zagnieżdżone struktury lub zbudować zupełnie nowy payload do wysłania do innej usługi.

jq to lekki i potężny procesor JSON działający w wierszu poleceń, który umożliwia wykonywanie takich przekształceń w jednym potoku. W tej lekcji poznają Państwo trzy podstawowe techniki zmiany struktury danych:

  • Tworzenie obiektów — zbudowanie nowego obiektu JSON od podstaw
  • map — zastosowanie przekształcenia do każdego elementu tablicy
  • to_entries / from_entries — potraktowanie par klucz-wartość obiektu jako tablicy, aby można było je filtrować i ponownie zbudować

Wszystkie przykłady zakładają, że jq jest zainstalowany (apt install jq / brew install jq).

Podstawy tworzenia obiektów

Najbardziej podstawową funkcją jq jest tworzenie obiektów: umieszczanie wyrażeń w {}, aby zbudować nowy obiekt JSON. Mogą Państwo wybrać pola, które mają zostać uwzględnione, oraz nadać im własne nazwy.

Składnia:

  • { newKey: .existingField } — zmiana nazwy pola
  • { name, age } — skrócona składnia, gdy nowy klucz ma taką samą nazwę jak pole
  • { total: (.price * .qty) } — obliczenie wartości bezpośrednio w wyrażeniu

Poniższy fragment odczytuje JSON produktu i tworzy jego uproszczoną strukturę z obliczanym polem subtotal.

#!/usr/bin/env bash
# Object construction: pick and rename fields
product='{
  "id": 42,
  "name": "Widget Pro",
  "price": 9.99,
  "qty": 3,
  "warehouse": "EU-West"
}'

echo "$product" | jq '{
  productId: .id,
  name,
  subtotal: (.price * .qty)
}'

Tworzenie obiektów z zagnieżdżonych danych

JSON spotykany w praktyce jest często zagnieżdżony. jq pozwala odwoływać się do zagnieżdżonych ścieżek wewnątrz konstruktora obiektu, jednocześnie spłaszczając strukturę.

W wyrażeniu określającym wartość konstruktora używają Państwo notacji ścieżki z kropkami:

  • { city: .address.city }
  • { lat: .location.coords.lat }

Poniższy przykład pobiera głęboko zagnieżdżony rekord użytkownika i tworzy płaskie podsumowanie, odpowiednie jako wiersz nagłówkowy pliku CSV lub treść żądania API.

#!/usr/bin/env bash
user='{
  "id": "u-001",
  "profile": {
    "displayName": "Ada Lovelace",
    "contact": { "email": "ada@example.com", "phone": "+44-700" }
  },
  "plan": "pro"
}'

echo "$user" | jq '{
  id,
  name: .profile.displayName,
  email: .profile.contact.email,
  plan
}'

Przekształcanie tablic za pomocą map

map(expr) jest odpowiednikiem jq konstrukcji for-each: stosuje expr do każdego elementu wejściowej tablicy i zwraca nową tablicę o tej samej długości.

Najważniejsze informacje:

  • map(expr) jest skróconym zapisem [.[] | expr]
  • Wyrażenie wewnątrz może być dowolnym filtrem jq — także tworzeniem obiektu
  • Można połączyć je z select(), aby filtrować dane przed przekształceniem

Poniższy fragment przetwarza listę zamówień, zachowując tylko pola potrzebne w wykazie wysyłkowym.

#!/usr/bin/env bash
orders='[
  {"orderId": 1, "customer": "Alice", "total": 42.50, "status": "shipped"},
  {"orderId": 2, "customer": "Bob",   "total": 18.00, "status": "pending"},
  {"orderId": 3, "customer": "Carol", "total": 99.99, "status": "shipped"}
]'

# Produce a shipping manifest: only shipped orders, slim fields
echo "$orders" | jq '[
  .[] | select(.status == "shipped") | {
    id: .orderId,
    recipient: .customer,
    amount: .total
  }
]'

map z polami obliczanymi

Wewnątrz map mogą Państwo obliczać nowe wartości, konwertować typy i łączyć pola — a nie tylko je kopiować. Typowe wzorce obejmują:

  • Interpolację ciągów znaków: "\(.first) \(.last)"
  • Działania arytmetyczne: (.price * 1.2 | round) dla narzutu w wysokości 20%
  • Wyrażenia warunkowe: if .score >= 90 then "A" else "B" end

Poniższy przykład wzbogaca listę pracowników, dodając obliczane pole fullName oraz etykietę seniority na podstawie liczby lat doświadczenia.

#!/usr/bin/env bash
staff='[
  {"first": "Grace", "last": "Hopper",  "years": 15},
  {"first": "Alan",  "last": "Turing",  "years": 4},
  {"first": "Linus", "last": "Torvalds","years": 9}
]'

echo "$staff" | jq 'map({
  fullName: "\(.first) \(.last)",
  years,
  seniority: (if .years >= 10 then "senior" elif .years >= 5 then "mid" else "junior" end)
})'

Zrozumienie to_entries

to_entries przekształca obiekt JSON w tablicę par {key, value}. Umożliwia to wykonywanie operacji na tablicach (map, select, sort) na polach obiektu — czego nie można zrobić bezpośrednio na obiekcie.

Przykładowe przekształcenie:

  • Wejście: {"a": 1, "b": 2}
  • Wyjście: [{"key": "a", "value": 1}, {"key": "b", "value": 2}]

Operacją odwrotną jest from_entries, która ponownie przekształca tę tablicę w obiekt. Razem tworzą idiom to_entries | map(...) | from_entries służący do przekształceń na poziomie obiektu.

#!/usr/bin/env bash
# Demonstrate to_entries and from_entries
config='{"host": "db.local", "port": 5432, "ssl": true}'

echo "--- to_entries output ---"
echo "$config" | jq 'to_entries'

echo "--- round-trip back to object ---"
echo "$config" | jq 'to_entries | from_entries'

Filtrowanie kluczy za pomocą to_entries

Jednym z najbardziej praktycznych zastosowań to_entries jest dynamiczne filtrowanie kluczy, które mają zostać zachowane lub usunięte, na podstawie samej nazwy klucza — czego nie można zrobić za pomocą tworzenia obiektu, gdy nazwy kluczy nie są wcześniej znane.

Wzorzec:

  • to_entries | map(select(.key | test("regex"))) | from_entries
  • to_entries | map(select(.key != "secret")) | from_entries

Poniższy fragment usuwa wszystkie klucze zaczynające się od podkreślenia (pola wewnętrzne/prywatne), zanim przekaże obiekt konfiguracji do zewnętrznej usługi.

#!/usr/bin/env bash
raw_config='{
  "endpoint": "https://api.example.com",
  "timeout": 30,
  "_internalToken": "s3cr3t",
  "_debugMode": true,
  "retries": 3
}'

# Remove any key starting with underscore
echo "$raw_config" | jq '
  to_entries
  | map(select(.key | startswith("_") | not))
  | from_entries
'

Dynamiczna zmiana nazw kluczy za pomocą to_entries

Tworzenie obiektu umożliwia zmianę nazw kluczy, gdy ich nazwy są znane w momencie zapisu. to_entries pozwala zmieniać nazwy kluczy programowo — na przykład konwertować camelCase na snake_case lub dodawać prefiks.

Wewnątrz map aktualizują Państwo pole .key każdego wpisu, a następnie przekazują wynik do from_entries:

  • map(.key |= gsub("(?<=[a-z])(?=[A-Z])"; "_") | .key |= ascii_downcase) — konwersja camelCase na snake_case
  • map(.key |= "app_" + .) — dodanie prefiksu do każdego klucza

Przykład dodaje prefiks APP_ do wszystkich nazw zmiennych środowiskowych, aby utworzyć dla nich przestrzeń nazw przed wstrzyknięciem do kontenera.

#!/usr/bin/env bash
env_vars='{"host": "localhost", "port": "8080", "debug": "false"}'

# Add APP_ prefix and uppercase all keys
echo "$env_vars" | jq '
  to_entries
  | map({ key: ("APP_" + (.key | ascii_upcase)), value })
  | from_entries
'

with_entries: wygodny skrót

Wzorzec to_entries | map(...) | from_entries jest tak często używany, że jq udostępnia jego skróconą wersję: with_entries(expr).

Jest dokładnie równoważny, ale bardziej zwięzły:

  • with_entries(.value |= . * 2) — podwojenie każdej wartości liczbowej
  • with_entries(select(.value != null)) — usunięcie kluczy, których wartości wynoszą null
  • with_entries(.key |= ascii_upcase) — zamiana wszystkich kluczy na wielkie litery

Poniższy fragment usuwa wszystkie klucze, których wartością jest null lub pusty ciąg znaków — to częsty etap czyszczenia danych przed wysłaniem żądania PATCH do interfejsu REST API.

#!/usr/bin/env bash
patch_body='{
  "name": "Mehmet",
  "email": "",
  "phone": null,
  "city": "Istanbul"
}'

# Drop empty/null fields before PATCH
cleaned=$(echo "$patch_body" | jq '
  with_entries(select(.value != null and .value != ""))
')

echo "Cleaned payload:"
echo "$cleaned"

# In practice you would pipe to curl:
# curl -s -X PATCH https://api.example.com/users/1 \
#   -H "Content-Type: application/json" \
#   -d "$cleaned"

Łączenie map i tworzenia obiektów w potoku

Rzeczywiste przekształcenia łączą wiele operacji jq. Typowy potok przygotowujący payload API może:

  1. Przefiltrować wejściową tablicę za pomocą map(select(...))
  2. Zmienić strukturę każdego elementu za pomocą tworzenia obiektu
  3. Dodać pola obliczane
  4. Posortować wynik

Poniższy przykład odczytuje listę metryk serwerów, zachowuje tylko serwery o wysokim użyciu procesora i tworzy zwięzły payload alertu gotowy do wysłania metodą POST do webhooka.

#!/usr/bin/env bash
metrics='[
  {"host": "web-01", "cpu": 23, "mem": 60, "region": "eu"},
  {"host": "web-02", "cpu": 91, "mem": 88, "region": "eu"},
  {"host": "db-01",  "cpu": 78, "mem": 95, "region": "us"},
  {"host": "db-02",  "cpu": 12, "mem": 40, "region": "us"}
]'

alerts=$(echo "$metrics" | jq '[
  .[] | select(.cpu > 75 or .mem > 85) | {
    server: .host,
    region,
    severity: (if .cpu > 90 or .mem > 90 then "critical" else "warning" end),
    metrics: { cpu: .cpu, mem: .mem }
  }
] | sort_by(.severity)')

echo "$alerts"

Budowanie nowego obiektu JSON z wielu źródeł

jq może scalać dane wejściowe i tworzyć obiekty korzystające z wielu źródeł JSON za pomocą operatora dodawania + oraz wiązania zmiennych z użyciem as $var.

Przydatne wzorce:

  • obj1 + obj2 — scalenie dwóch obiektów (w przypadku konfliktu kluczy wygrywa wartość po prawej stronie)
  • --argjson — przekazanie drugiego dokumentu JSON jako zmiennej
  • $ENV — bezpośredni odczyt zmiennych środowiskowych wewnątrz jq

Poniższy fragment scala podstawową konfigurację z nadpisaniami zależnymi od środowiska — to częsty wzorzec zarządzania konfiguracją aplikacji zgodnie z metodologią 12-factor w skryptach powłoki.

#!/usr/bin/env bash
base_config='{
  "logLevel": "info",
  "timeout": 30,
  "retries": 3,
  "database": "postgres://db.local/app"
}'

env_overrides='{
  "logLevel": "debug",
  "database": "postgres://db.staging/app_staging"
}'

# Merge: overrides win on conflicts
merged=$(echo "$base_config" | jq --argjson overrides "$env_overrides" '. + $overrides')

echo "Merged config:"
echo "$merged"

Sprawdzenie wiedzy: to_entries a map

Mają Państwo następujący obiekt JSON i należy usunąć wszystkie klucze, których wartość jest mniejsza od 0, tworząc nowy obiekt zawierający wyłącznie wartości nieujemne. Które wyrażenie jq poprawnie realizuje to zadanie?

Wejście: {"a": 10, "b": -3, "c": 0, "d": 5}

Podsumowanie lekcji: przekształcanie JSON za pomocą jq

Omówiono najważniejsze techniki zmiany struktury JSON za pomocą jq:

  • Tworzenie obiektów {} — budowanie nowych obiektów przez wybieranie, zmianę nazw i obliczanie pól na podstawie danych wejściowych
  • map(expr) — stosowanie dowolnego przekształcenia do każdego elementu tablicy, w tym tworzenie zagnieżdżonych obiektów i używanie select() do filtrowania
  • to_entries / from_entries — konwersja obiektu na tablicę par {key, value}, co umożliwia operacje na kluczach i wartościach, a następnie konwersja z powrotem
  • with_entries(expr) — zwięzły skrót pełnego potoku to_entries → map → from_entries
  • Scalanie obiektów za pomocą + i --argjson w payloadach pochodzących z wielu źródeł

Te elementy można łączyć: filtrować za pomocą select, zmieniać strukturę przez tworzenie obiektów, wzbogacać danymi obliczanymi i łączyć wszystko w jednym czytelnym wyrażeniu jq. Opanowanie tych wzorców pozwala przetwarzać praktycznie dowolny payload JSON bezpośrednio w powłoce, bez pisania osobnego skryptu w Pythonie lub Node.

Często zadawane pytania

Czy lekcja „Przekształcanie i tworzenie obiektów JSON za pomocą jq” jest bezpłatna?

Tak — pełny tekst „Przekształcanie i tworzenie obiektów JSON za pomocą jq” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Linux Command Line & Bash Scripting Mastery, przejdź na CoddyKit PRO. Kurs Linux Command Line & Bash Scripting Mastery zawiera 4 lekcji w sumie.

Co nauczysz się w „Przekształcanie i tworzenie obiektów JSON za pomocą jq”?

Przekształcaj dane za pomocą map, to_entries i konstruowania obiektów, aby tworzyć nowe ładunki JSON. Ćwiczysz Linux Command Line & Bash Scripting Mastery z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Linux Command Line & Bash Scripting Mastery?

Nie wymagamy żadnego doświadczenia. Linux Command Line & Bash Scripting Mastery w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Przekształcanie i tworzenie obiektów JSON za pomocą jq”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Linux Command Line & Bash Scripting Mastery?

Tak. Każda lekcja Linux Command Line & Bash Scripting Mastery zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Filtrowanie i wybieranie JSON za pomocą potoków jq
  2. Przekształcanie i tworzenie obiektów JSON za pomocą jq
  3. Korzystanie z REST API za pomocą curl i jq
  4. Edycja plików konfiguracyjnych YAML za pomocą yq
← Powrót do Linux Command Line & Bash Scripting Mastery