jq One-Liners تصفية وتحويل JSON من السطر الأوسع دون كتابة برنامج

تحديث في

سبع وصفات عملية لـ jq لمهندسي الخلفية والمسؤولين عن البنية التحتية — تشمل select، map، to_entries، del، group_by، وتحويل واجهات برمجة التطبيقات في الواقع. يُعرض المدخل والخرج لكل نمط.

أوامر jq المختصرة: تصفية وتحويل JSON من السطر الأوسع دون كتابة برنامج 1
إعلان · حذف؟

أنت تنظر إلى استجابة واجهة برمجة تطبيقات مُختصرة في موجه الأوامر. تحتاج إلى استخراج 3 حقول، وتصفية القيم المُعدة، وتحويل النتيجة إلى أمر آخر. كتابة سكربت بيثون لهذا يتطلب 20 سطرًا و2 دقائق لا تمتلكها. jq يُعالج ذلك في أمر واحد — إذا كنت تعرف الأنماط.

سبع وصفات أدناه. تغطي كل وصفة نمطًا ستجد استخدامه بشكل متكرر عند العمل مع استجابات واجهة برمجة تطبيقات أو ملفات سجل. تُعرض المدخلات والعمليات والنتائج لكل وصفة.

تثبيت

brew install jq        # macOS
apt-get install jq     # Ubuntu/Debian
apk add jq             # Alpine (Docker images)

الوصفة 1: استخراج حقل من كل عنصر في المصفوفة

الشيء الأكثر شيوعًا الذي ستفعله مع jq: استخراج حقل من كل عنصر في مصفوفة JSON.

المدخل (users.json)

[
  {"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"},
  {"id": 2, "name": "Bob",   "email": "bob@example.com",   "role": "user"},
  {"id": 3, "name": "Carol", "email": "carol@example.com", "role": "user"}
]
jq '.[].name' users.json
# → "Alice"
#   "Bob"
#   "Carol"  (newline-separated stream)

.[] يمر عبر كل عنصر في المصفوفة؛ .name يُستخرج الحقل. الناتج هو سلسلة — مفيد لتحويلها إلى أوامر أخرى. إذا كنت بحاجة إلى مصفوفة JSON كاملة:

jq 'map(.name)' users.json
# → ["Alice", "Bob", "Carol"]

map(.name) هي اختصار لـ [.[] | .name] — يُطبّق التعبير على كل عنصر ويُغلف النتائج في مصفوفة. ستجد أنك تستخدم map() بشكل متكرر.

الوصفة 2: التصفية باستخدام select

احتفظ فقط بالعناصر التي تتوافق مع شرط معين؛ احذف الباقي.

jq 'map(select(.role == "admin"))' users.json
[
  {"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"}
]

select(expr) يمر عبر العنصر فقط عندما يكون التعبير صحيحًا — يختفي كل شيء آخر. عند وضعه داخل map() يُحتفظ بالنتيجة كمصفوفة. أمثلة إضافية:

# Numeric comparison
jq 'map(select(.score > 80))' results.json

# Not-null check
jq 'map(select(.error != null))' events.json

# String contains (requires test)
jq 'map(select(.message | test("timeout")))' logs.json

الوصفة 3: إعادة تشكيل الكائنات باستخدام map

اختر فقط الحقول التي تحتاجها وقم بتعديل أسمائها بشكل اختياري في نفس العملية.

jq 'map({name: .name, role: .role})' users.json
[
  {"name": "Alice", "role": "admin"},
  {"name": "Bob",   "role": "user"},
  {"name": "Carol", "role": "user"}
]

أنت تُنشئ كائنًا جديدًا لكل عنصر. لتعديل اسم مفتاح، قم بتغيير الجانب الأيسر من العلامة:

jq 'map({username: .name, access_level: .role})' users.json

مختصر يوفر تقليلًا في عدد الأزرار: {name} تُليها {name: .name}. إذا كنت ترغب في الحقل كما هو، لا تحتاج إلى كتابة المفتاح مرتين:

jq 'map({id, name, role})' users.json

الوصفة 4: إعادة تسمية المفاتيح باستخدام to_entries و from_entries

map مثالي عندما تعرف أن المفاتيح موجودة. عندما تحتاج إلى تغيير المفاتيح نفسها — إضافة مقدمة، تغيير نمط التسمية، أو إعادة تسمية بناءً على مرجع — to_entries هي النمط الصحيح.

المدخل (config.json)

{"api_url": "https://api.example.com", "timeout": 30, "retry_count": 3}
# Add cfg_ prefix to every key
jq 'to_entries | map(.key = "cfg_" + .key) | from_entries' config.json
{"cfg_api_url": "https://api.example.com", "cfg_timeout": 30, "cfg_retry_count": 3}

to_entries تُحول {"k": "v"} داخل [{"key": "k", "value": "v"}]. بعد تغيير العناصر في المصفوفة الناتجة، from_entries تُعيد بناء الكائن. لتعديل مفتاح واحد فقط دون تغيير الباقي:

jq 'to_entries | map(if .key == "api_url" then .key = "endpoint" else . end) | from_entries' config.json

الوصفة 5: إزالة الحقول باستخدام del

العكس المعاكس للإعادة التشكيل: احتفظ بكل شيء واحذف بعض الحقول المحددة. الاستخدام الرئيسي هو إزالة البيانات الحساسة قبل تسجيلها أو قبل إرسال محتوى إلى خدمة خارجية.

jq 'map(del(.email))' users.json
[
  {"id": 1, "name": "Alice", "role": "admin"},
  {"id": 2, "name": "Bob",   "role": "user"},
  {"id": 3, "name": "Carol", "role": "user"}
]

احذف عدة حقول في نفس الوقت، أو حذف مسارات مُضمنة:

# Multiple top-level fields at once
jq 'del(.password, .token, .refresh_token)' user.json

# Nested path
jq 'del(.user.internal_id)' response.json

# All fields named "debug" at any depth (recursive descent)
jq 'del(.. | .debug? // empty)' response.json

الوصفة 6: التصفية، إعادة التشكيل، والترتيب في نفس العملية

الإيجابية الحقيقية هي تسلسل هذه الوحدات الأساسية. إليك نمطًا يظهر بشكل متكرر عند العمل مع استجابات واجهة برمجة تطبيقات مُقسّمة: الدخول إلى مصفوفة مُضمنة، التصفية، إعادة تشكيل الكائنات، وترتيب النتيجة.

المدخل (repos.json)

{
  "total_count": 3,
  "items": [
    {"id": 1, "name": "repo-alpha", "stargazers_count": 142, "language": "Go",     "private": false},
    {"id": 2, "name": "repo-beta",  "stargazers_count": 89,  "language": "Python", "private": true},
    {"id": 3, "name": "repo-gamma", "stargazers_count": 310, "language": "Go",     "private": false}
  ]
}
jq '.items
  | map(select(.private == false and .language == "Go"))
  | sort_by(-.stargazers_count)
  | map({name, stars: .stargazers_count})' repos.json
[
  {"name": "repo-gamma", "stars": 310},
  {"name": "repo-alpha", "stars": 142}
]

السلسلة:

  • .items — الدخول إلى المصفوفة المضمنة
  • map(select(...)) — التصفية في عملية واحدة؛ and تُربط شروط
  • sort_by(-.stargazers_count) — تُعكس القيمة للترتيب المتناقص؛ sort_by(.field) بحد ذاتها تُعطي ترتيبًا تصاعديًا
  • map({name, stars: .stargazers_count}) — التشكيل النهائي؛ {name} هي اختصار لـ {name: .name}

الوصفة 7: تحليل تكرار مستويات السجلات باستخدام group_by

تحليل التكرار على مخرجات السجلات المبنية — لا حاجة لقاعدة بيانات، ولا حاجة لعمليات awk معقدة.

المدخل (logs.json)

[
  {"level": "error", "msg": "connection timeout",     "service": "auth"},
  {"level": "info",  "msg": "request received",       "service": "api"},
  {"level": "error", "msg": "null pointer exception", "service": "worker"},
  {"level": "warn",  "msg": "slow query detected",    "service": "db"},
  {"level": "error", "msg": "rate limit exceeded",    "service": "api"}
]
jq 'group_by(.level) | map({level: .[0].level, count: length}) | sort_by(-.count)' logs.json
[
  {"level": "error", "count": 3},
  {"level": "info",  "count": 1},
  {"level": "warn",  "count": 1}
]

group_by(.level) تُرجع مصفوفة من مصفوفات — كل مصفوفة فرعية تحتوي على جميع العناصر التي تمتلك نفس قيمة المستوى. .[0].level تُأخذ اسم المستوى من العنصر الأول في المجموعة؛ length تُعدّ عدد العناصر في المجموعة.

أضف تحليلًا حسب الخدمة في نفس الاستعلام:

jq 'group_by(.level) | map({
  level:    .[0].level,
  count:    length,
  services: map(.service) | unique
})' logs.json

الرجوع السريع

الأنماط المذكورة أعلاه على شكل جدول عند الحاجة إلى تذكير سريع:

ما تريدهتعبير jq
جميع القيم الخاصة بالحقلmap(.field)
تصفية العناصر المطابقةmap(select(.field == "val"))
إعادة تشكيل كل كائنmap({newKey: .oldKey})
إعادة تسمية جميع المفاتيحto_entries | map(.key = ...) | from_entries
إزالة الحقولmap(del(.field1, .field2))
ترتيب تصاعديsort_by(.field)
ترتيب متناقصsort_by(-.field)
حساب التكرار حسب المجموعةgroup_by(.field) | map({key: .[0].field, count: length})
استرجاع جميع المفاتيح من الكائنkeys
حساب العناصر في المصفوفةlength
القيم المميزة الخاصة بالحقلmap(.field) | unique

قبل البدء: تهدئة الكتلة

تُرجع الاستجابات من واجهة برمجة تطبيقات غالبًا بشكل مختصر أو مُضمن بشكل عميق. إذا لم تكن متأكدًا من المسار الذي تحتاجه، قم بوضع JSON داخل تنسيق JSON — يُظهر التصحيح بعناصر قابلة للانكماش بحيث يمكنك رؤية المسار قبل كتابة التعبير jq بعد تنفيذ تغيير، يكون الأداة مفيدة لتأكيد الفرق قبل وبعد عند إعادة التشكيل أو إزالة الحقول، وتحقيق تأكيد على عدم حدوث تغيير غير متوقع. مقارنة جيسون تغطي هذه السبعة أنماط معظم عمليات التعديل على JSON التي ستجد استخدامها في السطر الأوامر. القوة الحقيقية تكمن في تسلسلها — بمجرد أن تتمكن من التصفية، إعادة التشكيل، والترتيب، يمكنك معالجة معظم استجابات واجهة برمجة تطبيقات دون الحاجة إلى ملف سكربت.

jq One-Liners: التصفية والتحويل من JSON من خلال السطر الأوامر دون كتابة سكربت 2

هل تريد حذف الإعلانات؟ تخلص من الإعلانات اليوم

تثبيت ملحقاتنا

أضف أدوات IO إلى متصفحك المفضل للوصول الفوري والبحث بشكل أسرع

أضف لـ إضافة كروم أضف لـ امتداد الحافة أضف لـ إضافة فايرفوكس أضف لـ ملحق الأوبرا

وصلت لوحة النتائج!

لوحة النتائج هي طريقة ممتعة لتتبع ألعابك، يتم تخزين جميع البيانات في متصفحك. المزيد من الميزات قريبا!

إعلان · حذف؟
إعلان · حذف؟
إعلان · حذف؟

ركن الأخبار مع أبرز التقنيات

شارك

ساعدنا على الاستمرار في تقديم أدوات مجانية قيمة

اشتري لي قهوة
إعلان · حذف؟