Skip to content

3. JSON va YAML — jq, yq

🎯 Bu bobda nimani o'rganasiz:

  • jq asoslari — identity, field access, array operatsiyalari
  • Filter va transformselect, map, group_by, sort_by
  • Object yaratish{name: .a, age: .b}
  • String va son operatsiyalari
  • curl + jq — eng kuchli pipeline (har DevOps kunlik vositasi)
  • yq — YAML uchun bir xil sintaksis
  • Real misollar — GitHub API, AWS, Kubernetes

⏱ Vaqt: ~35 daqiqa 🧪 Mashqlar: bashlings watch 13_jq (kelajak sprint)


3.1. Nima uchun jq kerak?

DevOps va SRE ish kunining 60-70%i — JSON. API javoblari, Kubernetes manifestlari, AWS CLI chiqishi, Docker inspect, GitHub Actions output. Hammasi JSON.

Bashda JSON'ni grep yoki awk bilan parse qilish — xavfli va xato:

bash
# ❌ XAVFLI — qator tartibi yoki escape o'zgarsa singadi
curl -s api.com/user | grep '"name"' | cut -d'"' -f4

jq — JSON uchun yaratilgan, JSON tushunadigan vosita. Strukturani anglaydi, regex'ga umid bermaydi.

bash
# ✓ TO'G'RI — strukturali
curl -s api.com/user | jq -r '.name'

Asosiy g'oya

JSON bilan ishlasangiz — jq ishlating. Hech qachon grep/awk bilan JSON parse qilmang.


3.2. O'rnatish

bash
# macOS
brew install jq

# Ubuntu / Debian
sudo apt install jq

# Alpine
apk add jq

# Statik binary (har joyda)
curl -L https://github.com/jqlang/jq/releases/latest/download/jq-linux-amd64 -o /usr/local/bin/jq
chmod +x /usr/local/bin/jq

# Versiya tekshirish
jq --version
# jq-1.7.1

3.3. Identity filter va pretty-print

Eng oddiy — identity filter .:

bash
echo '{"name":"Ali","age":25}' | jq '.'

Natija (pretty-formatted, ranglangan):

json
{
  "name": "Ali",
  "age": 25
}

Asosiy flaglar

FlagMazmuni
-rRaw — string'lardan qo'shtirnoq olib tashlash
-cCompact — bir qatorda
-sSlurp — barcha inputni bitta array deb o'qish
-nNull input (jq generatsiya qiladi)
-eExit code (null yoki false chiqsa → 1)
-SSort keys
-aASCII-only output (escape unicode)
--tabTab bilan indent
bash
# Raw (qo'shtirnoqsiz)
echo '"hello"' | jq '.'    # "hello"
echo '"hello"' | jq -r '.' # hello

# Compact
echo '{"a":1,"b":2}' | jq -c '.'
# {"a":1,"b":2}

-r har doim shellda ishlatish uchun

Agar jq natijasini shell o'zgaruvchisiga yozasiz, -r majburiy. Aks holda "qo'shtirnoq" ichida saqlanadi.

bash
name=$(echo '{"name":"Ali"}' | jq '.name')
echo "$name"            # "Ali"  ← qo'shtirnoq qoldi
name=$(echo '{"name":"Ali"}' | jq -r '.name')
echo "$name"            # Ali     ← toza

3.4. Field access

Sodda field

bash
echo '{"name":"Ali","age":25,"city":"Toshkent"}' | jq -r '.name'
# Ali

echo '{"name":"Ali","age":25}' | jq '.age'
# 25

Nested field

bash
echo '{"user":{"email":"ali@example.com","verified":true}}' | jq -r '.user.email'
# ali@example.com

Bracket notation (maxsus belgilar uchun)

bash
# Kalit ichida bo'shliq, raqamlar yoki tire bo'lsa
echo '{"user-id":42}' | jq '.["user-id"]'
# 42

Optional access — ?

bash
# Maydon bo'lmasa — null (xato emas)
echo '{"name":"Ali"}' | jq '.email?'
# null

# Tirnoqsiz access:
echo '{"name":"Ali"}' | jq '.email'
# null

# Lekin agar input string yoki array bo'lsa, .field xato beradi —
# `.field?` "silent fail" qiladi:
echo '"just a string"' | jq '.email?'    # null (xato emas)
echo '"just a string"' | jq '.email'     # ERROR

3.5. Array operatsiyalari

bash
# Misol input:
data='[10, 20, 30, 40, 50]'

Indeks bo'yicha

bash
echo "$data" | jq '.[0]'    # 10
echo "$data" | jq '.[-1]'   # 50 (oxirgi)
echo "$data" | jq '.[2]'    # 30

Slice — .[start:end]

bash
echo "$data" | jq '.[1:3]'  # [20, 30] (1..2 indekslar)
echo "$data" | jq '.[:2]'   # [10, 20] (boshidan 2 ta)
echo "$data" | jq '.[-2:]'  # [40, 50] (oxirgi 2 ta)

Iteratsiya — .[]

bash
echo "$data" | jq '.[]'
# 10
# 20
# 30
# 40
# 50

.[] — har elementni alohida (multi-output).

Hajm — length

bash
echo "$data" | jq 'length'                    # 5
echo '{"a":1,"b":2,"c":3}' | jq 'length'      # 3 (object keys soni)
echo '"hello"' | jq 'length'                  # 5 (belgi soni)

Object'lar massivi

bash
users='[
  {"name":"Ali","age":25},
  {"name":"Vali","age":30},
  {"name":"Gulnora","age":28}
]'

# Hammasini chiqarish
echo "$users" | jq '.[]'

# Faqat ismlar
echo "$users" | jq -r '.[].name'
# Ali
# Vali
# Gulnora

# Faqat 2-element ismi
echo "$users" | jq -r '.[1].name'   # Vali

3.6. Pipe | ichida zanjirlash

jq ichida | — bashning | bilan o'xshash, lekin filter'lar zanjiri.

bash
echo "$users" | jq '.[] | .name'
# Ali
# Vali
# Gulnora

echo "$users" | jq '.[] | .name | ascii_upcase'
# ALI
# VALI
# GULNORA

| chap natijani o'ng tomonga uzatadi — xuddi shell pipe kabi.


3.7. Filter — select(...)

select(condition) — shartga mos kelganlarini qoldiradi.

bash
echo "$users" | jq '.[] | select(.age >= 28)'
# {"name":"Vali","age":30}
# {"name":"Gulnora","age":28}

echo "$users" | jq -r '.[] | select(.age >= 28) | .name'
# Vali
# Gulnora

Operatorlar

OperatorMisol
==.age == 25
!=.status != "deleted"
>, <.score > 80
>=, <=.age >= 18
and.age > 18 and .verified
or.role == "admin" or .role == "owner"
not`.deleted

Mavjudligini tekshirish

bash
# Maydon mavjudmi?
echo '{"a":1}' | jq 'has("a")'    # true
echo '{"a":1}' | jq 'has("b")'    # false

# String yoki array elementi
echo '"hello world"' | jq 'contains("world")'   # true
echo '[1,2,3]' | jq 'contains([2])'             # true

3.8. map(...) — transform

map(f)[ .[] | f ] ning qisqartmasi.

bash
# Har yoshga 1 qo'shish
echo "$users" | jq 'map(.age + 1)'
# [26, 31, 29]

# Object'larni transform qilish
echo "$users" | jq 'map({ism: .name, yosh: .age})'
# [
#   {"ism":"Ali","yosh":25},
#   ...
# ]

3.9. Object yaratish

bash
# Yangi object yasash
echo '{"firstName":"Ali","lastName":"Karim"}' | jq '{
  fullName: (.firstName + " " + .lastName),
  initials: (.firstName[0:1] + .lastName[0:1])
}'
# {
#   "fullName": "Ali Karim",
#   "initials": "AK"
# }

to_entries va from_entries

Object'ni key-value pairs massiviga aylantirish:

bash
echo '{"name":"Ali","age":25}' | jq 'to_entries'
# [
#   {"key":"name","value":"Ali"},
#   {"key":"age","value":25}
# ]

# Teskari:
echo '[{"key":"a","value":1},{"key":"b","value":2}]' | jq 'from_entries'
# {"a":1,"b":2}

Foydali pattern — har value'ni transform qilish:

bash
# Har qiymatni stringga aylantirish
echo '{"a":1,"b":2}' | jq 'with_entries(.value |= tostring)'
# {"a":"1","b":"2"}

3.10. group_by, sort_by, unique_by

bash
people='[
  {"name":"Ali","dept":"IT","age":25},
  {"name":"Vali","dept":"HR","age":30},
  {"name":"Gulnora","dept":"IT","age":28},
  {"name":"Bobur","dept":"HR","age":35}
]'

# Bo'lim bo'yicha guruhlash
echo "$people" | jq 'group_by(.dept)'

# Yosh bo'yicha tartiblash
echo "$people" | jq 'sort_by(.age) | .[].name'
# "Ali"
# "Gulnora"
# "Vali"
# "Bobur"

# Teskari
echo "$people" | jq 'sort_by(.age) | reverse | .[].name'

# Unique
echo "$people" | jq 'unique_by(.dept) | .[].dept'
# "HR"
# "IT"

Bo'lim bo'yicha hisoblash

bash
echo "$people" | jq 'group_by(.dept) | map({
  dept: .[0].dept,
  count: length,
  avg_age: (map(.age) | add / length)
})'
# [
#   {"dept":"HR","count":2,"avg_age":32.5},
#   {"dept":"IT","count":2,"avg_age":26.5}
# ]

3.11. String va son operatsiyalari

Stringlar

FunksiyaMisol
ascii_upcase`"hello"
ascii_downcase`"HELLO"
length`"hello"
split(",")`"a,b,c"
join("-")`["a","b"]
gsub("re"; "x")Global regex replace
sub("re"; "x")Birinchi regex moslash
ltrimstr("pre")Prefix olib tashlash
rtrimstr(".log")Suffix olib tashlash
tostringNumber → string
tonumberString → number
bash
echo '"hello world"' | jq -r 'ascii_upcase'
# HELLO WORLD

echo '["a","b","c"]' | jq -r 'join(",")'
# a,b,c

echo '"app-prod-v2.tar.gz"' | jq -r 'ltrimstr("app-") | rtrimstr(".tar.gz")'
# prod-v2

Sonlar

FunksiyaMazmuni
addArray yig'indi
min, maxEng kichik / katta
floor, ceilYaxlitlash
fabsAbsolyut qiymat
bash
echo '[10,20,30,40]' | jq 'add'           # 100
echo '[10,20,30,40]' | jq 'min'           # 10
echo '[10,20,30,40]' | jq 'max'           # 40
echo '[1.4,2.6]' | jq 'map(floor)'        # [1, 2]

3.12. curl + jq — eng kuchli pipeline

Top 5 GitHub repositoriya'lari (yulduzlar)

bash
curl -s "https://api.github.com/search/repositories?q=language:rust&sort=stars" \
  | jq -r '.items[:5] | .[] | "\(.stargazers_count) \(.full_name)"'
# 96234 rust-lang/rust
# 78912 denoland/deno
# ...

GitHub foydalanuvchi haqida ma'lumot

bash
curl -s https://api.github.com/users/torvalds | jq '{
  name: .name,
  bio: .bio,
  repos: .public_repos,
  followers: .followers
}'
# {
#   "name": "Linus Torvalds",
#   "bio": null,
#   "repos": 6,
#   "followers": 235000
# }

Bitta maydonni shell o'zgaruvchiga

bash
STARS=$(curl -s https://api.github.com/repos/rust-lang/rust | jq '.stargazers_count')
echo "Rust starlari: $STARS"

Filter + transform

bash
# Faqat ochiq issue'lar, eng so'nggi 5 tasi
curl -s "https://api.github.com/repos/cli/cli/issues?state=open" \
  | jq -r '.[:5] | .[] | "[\(.number)] \(.title) — \(.user.login)"'

Multi-source — jq -s (slurp)

Bir nechta JSON inputni bitta array qilib o'qish:

bash
curl -s api1.com > a.json
curl -s api2.com > b.json

jq -s '.[0] + .[1]' a.json b.json
# Ikkalasini birlashtirish

3.13. Conditionals — if-then-else-end

bash
echo '{"age":17}' | jq 'if .age >= 18 then "kattalar" else "yoshlar" end'
# "yoshlar"

echo '{"age":25}' | jq 'if .age >= 18 then "kattalar" else "yoshlar" end'
# "kattalar"

elif ham bor:

bash
echo '{"score":85}' | jq '
  if .score >= 90 then "A"
  elif .score >= 70 then "B"
  elif .score >= 50 then "C"
  else "F"
  end
'
# "B"

3.14. yq — YAML uchun

yq (Mike Farah versiyasi, Go'da yozilgan) — jq bilan bir xil sintaksis YAML uchun.

bash
# O'rnatish
brew install yq                # macOS
sudo snap install yq           # Ubuntu

# Versiya
yq --version

Kubernetes manifest o'qish

bash
cat deployment.yaml | yq '.spec.replicas'
# 3

# Konteyner image'ini ko'rish
yq '.spec.template.spec.containers[0].image' deployment.yaml
# nginx:1.21

Qiymatni o'zgartirish (in-place)

bash
# replicas ni 5 ga
yq -i '.spec.replicas = 5' deployment.yaml

# Tag yangilash
yq -i '.spec.template.spec.containers[0].image = "nginx:1.25"' deployment.yaml

YAML ↔ JSON konvertatsiya

bash
# YAML → JSON
yq -o=json deployment.yaml > deployment.json

# JSON → YAML
yq -p=json -o=yaml deployment.json

yq versiyalari farqli

Ikki mashhur yq bor:

  • Mike Farah (Go)jq sintaksis, bu yerda ko'rsatilgan
  • Python (kislyuk/yq)jq wrapper, sintaksis biroz farqli

yq --version orqali qaysi versiyangiz borligini tekshiring.


3.15. Real production misollar

Misol 1 — AWS EC2 instance'larni filtrlash

bash
aws ec2 describe-instances \
  | jq -r '.Reservations[].Instances[]
           | select(.State.Name == "running")
           | "\(.InstanceId) \(.InstanceType) \(.PublicIpAddress)"'
# i-0abc123 t3.medium 54.232.x.x
# i-0def456 t3.large  18.231.x.x

Misol 2 — Docker konteyner cleanup

bash
# 1 soatdan ko'p ishlovchi `Exited` konteynerlar
docker ps -a --format '{{json .}}' \
  | jq -r 'select(.State == "exited" and (.RunningFor | test("hour"))) | .ID' \
  | xargs -r docker rm

Misol 3 — Kubernetes Pod statuslari

bash
kubectl get pods -o json \
  | jq -r '.items[]
           | "\(.metadata.namespace)/\(.metadata.name) — \(.status.phase)"' \
  | sort -k2
# default/web-abc — Running
# default/web-def — Pending
# kube-system/coredns — Running

Misol 4 — Log fayl tahlili (JSON log format)

bash
# Apache structured logs
cat access.log | jq -r 'select(.status >= 500) | "\(.timestamp) \(.path) \(.status)"' \
  | head -20

Misol 5 — Konfiguratsiya backup audit

bash
# Kubernetes deployment image versiyalari
for f in deployments/*.yaml; do
    image=$(yq '.spec.template.spec.containers[0].image' "$f")
    printf '%-30s %s\n' "$(basename "$f")" "$image"
done

3.16. Tez-tez uchraydigan xatolar

Klassik tuzoqlar

  1. -r flagini unutish.

    bash
    user=$(... | jq '.name')      # "Ali" — qo'shtirnoq qoldi!
    user=$(... | jq -r '.name')   # Ali — toza
  2. null qiymatlarni handle qilmaslik.

    bash
    email=$(... | jq -r '.email')   # agar yo'q bo'lsa "null" qaytaradi (string!)
    email=$(... | jq -r '.email // empty')   # bo'sh string
  3. Object access yo'qida xato.

    bash
    ... | jq '.user.email'        # user yo'q bo'lsa — XATO
    ... | jq '.user.email?'       # null qaytaradi
  4. map ichida .[] ishlatish.

    bash
    echo '[1,2,3]' | jq 'map(.[])'   # XATO
    echo '[1,2,3]' | jq 'map(. * 2)' # ✓
  5. CSV'ga export uchun @csv unutish.

    bash
    ... | jq -r '[.name, .age] | @csv'
    # "Ali",25
  6. jq arifmetik darajalik (precision). Katta sonlar IEEE 754 double'ga aylanadi — 16-17 ta raqamdan keyin precision yo'qoladi.

  7. Numeric vs string comparison.

    bash
    echo '{"v":"5"}' | jq '.v > 3'   # XATO (string vs number)
    echo '{"v":"5"}' | jq '(.v | tonumber) > 3'   # ✓
  8. jq newline'lar bilan tashvish. Multiline string olishingiz mumkin — -c (compact) ishlatib bir qatorga aylantirin.


3.17. Mashqlar

🧪 Kelajakda bashlings watch 13_jq paketida.

  1. Foydalanuvchi nomi{"user":{"name":"Ali","email":"ali@example.com"}} JSON dan faqat email'ni jq -r bilan oling.

  2. Filter[{"age":15},{"age":20},{"age":17},{"age":30}] dan kattalar (>=18) sonini chiqaring.

  3. GitHub starscurl -s https://api.github.com/repos/cli/cli | jq -r '.stargazers_count' orqali GitHub CLI ning yulduzlar sonini oling.

  4. CSV transform[{"name":"Ali","age":25},{"name":"Vali","age":30}] ni CSV ko'rinishida chiqaring (@csv orqali).

  5. YAML edit — har qanday deployment.yaml faylida replicas ni 3 dan 5 ga in-place (-i) o'zgartiring.


3.18. Xulosa

TushunchaAsosiy nuqta
jq '.'Identity, pretty-print
jq '.field'Sodda field access
jq '.user.email'Nested
jq '.field?'Optional access (null-safe)
jq '.[0]' / jq '.[]'Array indeks / iteratsiya
jq 'length'Hajm
`jq '...select(...)'`
jq 'map(...)'Transform
jq 'group_by(.x)'Guruhlash
jq '{a: .b}'Object yaratish
jq 'if X then Y else Z end'Shart
jq -rRaw — har shell o'zgaruvchisida majburiy
jq -cCompact bir qator
jq -sSlurp — barcha inputni array deb o'qish
yq '...'XaShu sintaksis YAML uchun

5 ta asosiy g'oya

  1. jq har JSON ishidagrep/awk bilan JSON parse qilmang.
  2. -r har shell o'zgaruvchisi uchun — qo'shtirnoq olib tashlash uchun.
  3. null ehtiyot? (optional) yoki // empty default ishlating.
  4. curl + jq pipeline — DevOps'ning eng ko'p ishlatadigan zanjiri.
  5. yq (Mike Farah)jq sintaksisi YAML uchun. Kubernetes va Docker Compose'da kerak.

🎉 Endi sizda API integratsiya uchun barcha vositalar bor: curl + jq + yq. Keyingi bobda cron va systemd timer'lar — vazifalarni rejalashtirish.

Keyingi sahifa: 4. Cron va vazifalarni rejalashtirish →

MIT litsenziyasi asosida tarqatiladi.