sed va awk — matnni o'zgartirish va ustunlar
Muammodan boshlaylik
Ikki vazifa:
- 50 ta konfiguratsiya faylida
localhost:3306nidb.dokon.uz:3306ga almashtirish kerak. Har birini muharrirda ochasizmi? sotuvlar.csvda har bir shahar bo'yicha sotuvlar yig'indisini hisoblash kerak.cutvauniqfaqat sanaydi — qo'shish ular qo'lidan kelmaydi.
Birinchi vazifa — sed uchun, ikkinchisi — awk uchun. Ikkalasi ham to'liq dasturlash tillari, lekin 90% holatlarda bir nechta oddiy naqsh yetarli.
sed — oqim muharriri
sed (stream editor) matnni qatorma-qator o'qiydi va o'zgartiradi — muharrirni ochmasdan.
Almashtirish: s/eski/yangi/
echo "Salom dunyo" | sed 's/dunyo/Toshkent/'
Salom Toshkent
sed 's/localhost/db.dokon.uz/' config.env # natija ekranga
sed 's/localhost/db.dokon.uz/g' config.env # g — qatordagi BARCHASI
g siz — har qatorda faqat birinchi topilgan almashtiriladi.
Faylni o'zgartirish: -i
sed -i 's/localhost/db.dokon.uz/g' config.env
sed -i.bak 's/localhost/db.dokon.uz/g' config.env # config.env.bak zaxira bilan
[!WARNING]
sed -ifaylni joyida o'zgartiradi — qaytarish yo'q. Avval-isiz ishga tushirib, natijani ekranda ko'ring. Yoki-i.bakbilan zaxira oling.
[!INFO] macOS da
sed -iboshqacha:sed -i '' 's/a/b/g' fayl. Linux da —sed -i 's/a/b/g' fayl.
Ko'p fayllarda
grep -rl "localhost:3306" config/ | xargs sed -i 's/localhost:3306/db.dokon.uz:3306/g'
grep -rl — qaysi fayllarda; xargs sed -i — hammasida almashtirish (15-dars).
Ajratuvchini o'zgartirish
Yo'llarda / ko'p — \/ bilan yozish noqulay. Istalgan belgi ajratuvchi bo'lishi mumkin:
sed 's/\/var\/www/\/opt\/app/g' nginx.conf # ❌ o'qish qiyin
sed 's|/var/www|/opt/app|g' nginx.conf # ✅
Boshqa sed buyruqlari
sed -n '10p' fayl.txt # faqat 10-qator
sed -n '10,20p' fayl.txt # 10–20 qatorlar
sed '5d' fayl.txt # 5-qatorni o'chirish
sed '/^#/d' nginx.conf # # bilan boshlanuvchi (izoh) qatorlarni o'chirish
sed '/^$/d' fayl.txt # bo'sh qatorlarni o'chirish
sed 's/^/ /' fayl.txt # har qator boshiga 2 bo'shliq
sed 's/[[:space:]]*$//' fayl.txt # qator oxiridagi bo'shliqlarni o'chirish
sed -i 's/\r$//' skript.sh # Windows qator oxirlarini tuzatish
-n + p — "faqat ko'rsatilganini chiqar".
Shartli almashtirish
sed '/^PORT=/s/3000/8080/' .env # faqat PORT= bilan boshlanuvchi qatorda
Amaliy misol: sozlamani o'zgartirish
sudo sed -i 's/^#\?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config
SSH da parol bilan kirishni o'chirish (42-dars): izohlangan (#) yoki yo'q — qatorni PasswordAuthentication no ga almashtiradi.
awk — ustunlar bilan ishlash
awk har bir qatorni avtomatik ustunlarga (maydonlarga) bo'ladi:
$1,$2, ... — 1, 2-ustun$0— butun qator$NF— oxirgi ustunNR— qator raqamiNF— ustunlar soni
Standart ajratuvchi — bo'shliqlar (bittami, o'ntami — farqi yo'q). Bu cut dan katta afzallik.
echo "Otabek 25 Toshkent" | awk '{print $1, $3}'
Otabek Toshkent
Tuzilma
awk 'SHART { HARAKAT }' fayl
ps aux | awk '{print $2, $11}' # PID va buyruq
ls -l | awk '{print $5, $9}' # hajm va nom
df -h | awk '{print $5, $6}' # foiz va mount
awk -F: '{print $1}' /etc/passwd # -F — ajratuvchi
awk -F',' '{print $2}' sotuvlar.csv
Shartlar
awk '$3 > 100' data.txt # 3-ustun 100 dan katta
awk -F',' '$2 == "Toshkent"' sotuvlar.csv # faqat Toshkent
awk '/ERROR/' app.log # grep kabi
awk 'NR > 1' sotuvlar.csv # sarlavhasiz
awk 'NF > 0' fayl.txt # bo'sh bo'lmagan qatorlar
awk '$9 >= 500' access.log # 5xx javoblar (Nginx)
Hisoblash — awk ning asosiy kuchi
# Jami
awk -F',' 'NR > 1 { jami += $4 } END { print "Jami:", jami }' sotuvlar.csv
Jami: 17
NR > 1— sarlavhani o'tkazib yuborishjami += $4— har qatorda qo'shishEND { }— barcha qatorlardan keyin bir marta
# Har bir shahar bo'yicha yig'indi
awk -F',' 'NR > 1 { s[$2] += $4 } END { for (sh in s) print sh, s[sh] }' sotuvlar.csv
Buxoro 1
Samarqand 7
Toshkent 9
s[$2] — massiv (lug'at): kalit — shahar, qiymat — yig'indi. Bu — SQL dagi GROUP BY + SUM.
# O'rtacha
awk '{ s += $1; n++ } END { print s / n }' sonlar.txt
# Papkadagi fayllar umumiy hajmi (MB)
ls -l | awk '{ s += $5 } END { printf "%.1f MB\n", s / 1024 / 1024 }'
# Nginx: o'rtacha javob hajmi
awk '{ s += $10 } END { print s / NR }' access.log
Formatlab chiqarish
awk -F',' 'NR > 1 { printf "%-12s %5d\n", $2, $4 }' sotuvlar.csv
Toshkent 3
Samarqand 5
...
printf — C dagi kabi: %s matn, %d butun son, %.2f kasr, %-12s — 12 belgilik chapga tekislangan.
sed yoki awk?
| Vazifa | Vosita |
|---|---|
| Matnni almashtirish (find & replace) | sed |
| Fayldagi qatorlarni o'chirish, chiqarish | sed |
| Konfiguratsiyani skriptda o'zgartirish | sed -i |
| Ustunni ajratish (bo'shliqlar bilan) | awk |
| Hisoblash: yig'indi, o'rtacha | awk |
| Guruhlash (GROUP BY) | awk |
| Murakkab mantiq | Python yoki boshqa til |
[!TIP] Agar awk buyrug'i bir necha qatordan oshib ketsa — bu Python skript yozish vaqti kelganining belgisi. awk — tez bir qatorli tahlil uchun.
Nima uchun shunday?
Nima uchun 1970-yillardagi sed va awk bugun ham ishlatiladi, Python bor bo'lsa ham?
Chunki ular har bir serverda allaqachon bor va bir qatorda ishlaydi. Serverda log tahlili uchun Python skript yozish — fayl yaratish, ochish, o'qish, ajratish, chop etish. awk da — awk '{s+=$10} END {print s}' access.log, 5 soniya. Bundan tashqari, ular oqim bilan ishlaydi: 20 GB faylni xotiraga yuklamasdan qatorma-qator qayta ishlaydi. sed esa skriptlarda va Dockerfile larda konfiguratsiyani avtomatik o'zgartirishning standart usuli bo'lib qoldi. Ular "katta" dasturlash tili emas — terminalning "kalkulyatori" va "qidir-almashtir" i.
Xulosa
Eslab qoling:
sed 's/eski/yangi/g'— almashtirish;-i— faylda (ehtiyot!),-i.bak— zaxira bilansed 's|a|b|g'— yo'llar uchun boshqa ajratuvchised -n '10,20p'— qatorlarni chiqarish;'/^#/d'— izohlarni o'chirishawk '{print $1, $3}'— ustunlar;-F','— ajratuvchi;$NF— oxirgiawk '$3 > 100'— filtrlash;NR > 1— sarlavhasizawk '{s += $2} END {print s}'— yig'indis[$1] += $2— guruhlash (GROUP BY)
Keyingi dars
17-dars: Mashqlar — log fayllarni tahlil qilish