تصفية JSON وتحديد عناصره باستخدام مسارات jq
تنقّل بين الكائنات والمصفوفات المتداخلة باستخدام محددات jq والأنابيب ومرشّح select
تصفية JSON وتحديد عناصره باستخدام مسارات jq درس مجاني في Linux Command Line & Bash Scripting Mastery على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Linux Command Line & Bash Scripting Mastery، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Linux Command Line & Bash Scripting Mastery 4 دروس في المجموع.
ما هو jq ولماذا نستخدمه؟
إن jq أداة خفيفة وقوية تعمل عبر سطر الأوامر لتحليل بيانات JSON وتصفيتها وتحويلها. وهي بمثابة sed الخاص بـ JSON — تمرر إليها JSON عبر أنبوب، فتحصل على إخراج منظم.
- تكون مثبتة مسبقًا في معظم توزيعات Linux أو يمكن تثبيتها عبر
apt install jq/brew install jq - تعمل بسلاسة ضمن مسارات أنابيب shell مع
curlوcatوغيرهما من الأدوات - تدعم التصفية والتعيين والاختزال وتحويل الصيغ
الاستدعاء الأساسي هو: jq '<filter>' file.json أو عبر أنبوب كما يلي: cat file.json | jq '<filter>'. والمرشح . (النقطة) هو مرشح الهوية — إذ يطبع المستند بأكمله بتنسيق جميل.
# Pretty-print a JSON file
jq '.' data.json
# Or pipe from curl
curl -s https://api.github.com/users/torvalds | jq '.'اختيار حقول الكائنات باستخدام تدوين النقطة
للوصول إلى حقل في كائن JSON، استخدم تدوين النقطة: .fieldName. ويمكنك تسلسل المحددات للتنقل في الكائنات المتداخلة.
.name— حقل من المستوى الأعلى.address.city— حقل متداخل."field-with-dash"— تحتاج الحقول التي تحتوي على محارف خاصة إلى وضعها بين علامتي اقتباس
إذا لم يكن الحقل موجودًا، يعيد jq القيمة null بدلًا من إصدار خطأ. وهذا يجعله آمنًا للاستخدام في البرامج النصية من دون عمليات تحقق إضافية من القيم الفارغة للحقول الاختيارية.
# Given: {"name":"Alice","address":{"city":"Berlin","zip":"10115"}}
echo '{"name":"Alice","address":{"city":"Berlin","zip":"10115"}}' | jq '.name'
# Output: "Alice"
echo '{"name":"Alice","address":{"city":"Berlin","zip":"10115"}}' | jq '.address.city'
# Output: "Berlin"الوصول إلى عناصر المصفوفات والتكرار عليها
يُوصل إلى مصفوفات JSON باستخدام تدوين الأقواس. ويستخدم jq فهرسة تبدأ من الصفر.
.items[0]— العنصر الأول.items[-1]— العنصر الأخير.items[1:3]— شريحة (من الفهرس 1 حتى ما قبل 3).items[]— تفجير المصفوفة: يُخرج كل عنصر كقيمة منفصلة (وهذا هو المكرّر)
يُعد المكرّر [] أساسيًا في مسارات jq — فهو يتيح لك تطبيق المرشحات اللاحقة على كل عنصر بشكل مستقل.
# Given an array of users
echo '[{"name":"Alice"},{"name":"Bob"},{"name":"Carol"}]' | jq '.[0]'
# Output: {"name":"Alice"}
# Iterate all elements and extract .name from each
echo '[{"name":"Alice"},{"name":"Bob"},{"name":"Carol"}]' | jq '.[].name'
# Output:
# "Alice"
# "Bob"
# "Carol"إنشاء مسارات jq باستخدام عامل الأنبوب
مثل أنبوب shell | تمامًا، يمتلك jq عامل أنبوب داخليًا خاصًا به. ويمرر هذا العامل ناتج أحد المرشحات بوصفه إدخالًا للمرشح التالي.
jq '.users[] | .name'— يكرّر على المستخدمين، ثم يستخرج اسم كل منهمjq '.data | .items[] | .id'— ينتقل إلى البيانات، ويفجّر العناصر، ثم يستخرج المعرّف
تتيح الأنابيب داخل تعبير jq إنشاء تحويلات معقدة خطوةً بخطوة. وتتلقى كل مرحلة ما أنتجته المرحلة السابقة، بما في ذلك القيم المتعددة الناتجة عن مكرّر.
الاستنتاج الأساسي: عندما ينتج مكرّر N من القيم، يُشغّل كل مرشح لاحق N مرة، مرة واحدة لكل قيمة.
# Nested pipeline: navigate -> iterate -> extract
echo '{"users":[{"name":"Alice","age":30},{"name":"Bob","age":25}]}' \
| jq '.users[] | .name'
# Output:
# "Alice"
# "Bob"
# Chain more stages
echo '{"users":[{"name":"Alice","age":30},{"name":"Bob","age":25}]}' \
| jq '.users[] | .age'
# Output:
# 30
# 25التصفية باستخدام select()
يمرر المرشح select(condition) القيمة فقط إذا كان الشرط صحيحًا؛ وإلا فلا ينتج أي إخراج. وهو المكافئ في jq لكل من grep أو WHERE في SQL.
select(.age > 18)— يحتفظ بالكائنات التي يزيد فيها العمر على 18select(.status == "active")— التحقق من التساويselect(.name | startswith("A"))— اختبار سلسلة نصية متداخل
اجمع بين select والمكرّر لتصفية المصفوفات: يعرض .items[] | select(.active) العناصر التي تكون فيها .active ذات قيمة منطقية صحيحة فقط.
# Filter array elements by a condition
echo '[{"name":"Alice","age":30},{"name":"Bob","age":17},{"name":"Carol","age":25}]' \
| jq '.[] | select(.age >= 18) | .name'
# Output:
# "Alice"
# "Carol"
# Filter by string equality
echo '[{"name":"Alice","role":"admin"},{"name":"Bob","role":"user"}]' \
| jq '.[] | select(.role == "admin") | .name'
# Output: "Alice"إعادة بناء الكائنات والمصفوفات باستخدام {} و[]
يتيح لك jq إعادة تشكيل البيانات من خلال إنشاء كائنات جديدة باستخدام {} ومصفوفات جديدة باستخدام [].
{name: .name, city: .address.city}— اختيار الحقول وإعادة تسميتها داخل كائن جديد[.items[] | .id]— جمع القيم المتكررة مرة أخرى في مصفوفة- اختصارًا:
{name, age}مكافئ لـ{name: .name, age: .age}
يُسمى إحاطة مسار أنابيب بين [...] إنشاء المصفوفة، وهو أمر أساسي عندما تريد أن يكون إخراجك مصفوفة JSON بدلًا من تدفق من القيم.
# Reshape: keep only selected fields
echo '[{"id":1,"name":"Alice","password":"secret"},{"id":2,"name":"Bob","password":"secret"}]' \
| jq '[.[] | {id, name}]'
# Output:
# [
# {"id": 1, "name": "Alice"},
# {"id": 2, "name": "Bob"}
# ]
# Collect filtered names into an array
echo '[{"name":"Alice","active":true},{"name":"Bob","active":false}]' \
| jq '[.[] | select(.active) | .name]'
# Output: ["Alice"]التعامل مع المصفوفات المتداخلة والاجتياز التكراري
غالبًا ما تكون بيانات JSON الواقعية متداخلة بعمق. يوفر jq أداتين للتنقل العميق:
.a.b.c— مسار صريح عندما تكون البنية معروفة.. | .fieldName?— الاجتياز التكراري: يجتاز كل عقدة في الشجرة ويُخرج القيم حيثما يوجد المفتاح
يمنع عامل ? (المحاولة) ظهور الأخطاء عندما لا يكون الحقل موجودًا في عقدة معينة، وهو أمر بالغ الأهمية عند استخدام الاجتياز التكراري على أشجار غير متجانسة.
استخدم الاجتياز التكراري بحذر مع المستندات الكبيرة — فهو يزور كل عقدة وقد يكون بطيئًا. وفضّل المسارات الصريحة عندما تكون البنية متوقعة.
# Explicit deep path
echo '{"a":{"b":{"c":42}}}' | jq '.a.b.c'
# Output: 42
# Recursive descent: find all "id" values anywhere in the tree
echo '{"users":[{"id":1,"profile":{"id":99}},{"id":2}]}' \
| jq '.. | .id?'
# Output:
# 1
# 99
# 2مثال عملي: تحليل استجابات API باستخدام curl
من أكثر حالات استخدام jq شيوعًا تحليل استجابات REST API التي جُلبت باستخدام curl. ويمنحك الجمع بين curl -s (الصامت) ومسار jq استخراجًا نظيفًا للبيانات وقابلًا للاستخدام في البرامج النصية.
- استخراج قيمة واحدة:
curl -s URL | jq '.field' - إنشاء جدول ملخص: التكرار على مصفوفة، وإعادة بناء كائنات تتضمن الحقول التي تحتاج إليها فقط
- استخدم
-r(الإخراج الخام) لإزالة علامات الاقتباس المحيطة بقيم السلاسل النصية — وهو أمر أساسي عند إسنادها إلى متغيرات shell
تلميح: أضف -r دائمًا عندما سيُستخدم إخراج jq كمتغير shell أو سيُمرر إلى أمر آخر.
#!/usr/bin/env bash
# Fetch GitHub repo info and extract specific fields
REPO="torvalds/linux"
RESPONSE=$(curl -s "https://api.github.com/repos/${REPO}")
# Extract fields
STARS=$(echo "$RESPONSE" | jq -r '.stargazers_count')
LANG=$(echo "$RESPONSE" | jq -r '.language')
DESC=$(echo "$RESPONSE" | jq -r '.description')
echo "Stars : $STARS"
echo "Lang : $LANG"
echo "Desc : $DESC"استخدام map() وmap_values()
يوفر jq دالتين ملائمتين من الرتبة العليا لتحويل المجموعات:
map(f)— يطبق المرشحfعلى كل عنصر في مصفوفة، ويعيد مصفوفة جديدة. وهو مكافئ لـ[.[] | f].map_values(f)— يطبقfعلى كل قيمة في كائن أو مصفوفة، مع الحفاظ على المفاتيح/الفهارس.
تتميز هاتان الدالتان بوضوح أكبر من إحاطة مسارات الأنابيب يدويًا بـ []، وتنسجمان مع أسلوب jq الاصطلاحي في التحويلات التي ينبغي أن تبقى مصفوفات.
# map: extract a field from each element
echo '[{"name":"Alice","score":95},{"name":"Bob","score":80}]' \
| jq 'map(.name)'
# Output: ["Alice", "Bob"]
# map with select: filter + transform in one step
echo '[{"name":"Alice","score":95},{"name":"Bob","score":60}]' \
| jq 'map(select(.score >= 70) | .name)'
# Output: ["Alice"]
# map_values: multiply every value in an object by 2
echo '{"a":1,"b":2,"c":3}' | jq 'map_values(. * 2)'
# Output: {"a":2,"b":4,"c":6}التعامل مع الحقول الاختيارية والقيم الافتراضية باستخدام //
غالبًا ما تكون بيانات JSON من المصادر الخارجية غير متسقة — فقد تكون الحقول مفقودة أو null. يوفر jq عامل البديل // (الشرطتين المائلتين) لتوفير قيمة افتراضية.
.nickname // "anonymous"— استخدم.nicknameإذا لم تكن قيمته null أو false، وإلا فاستخدم"anonymous".count // 0— قيمة افتراضية عددية- الدمج مع
select:select((.status // "inactive") == "active")
وهذا أكثر اختصارًا بكثير من المكافئ في shell، وهو ${VAR:-default}، كما أنه يندمج بسلاسة داخل مسارات أطول.
# Provide defaults for missing/null fields
echo '[{"name":"Alice","role":"admin"},{"name":"Bob"}]' \
| jq '[.[] | {name, role: (.role // "user")}]'
# Output:
# [
# {"name": "Alice", "role": "admin"},
# {"name": "Bob", "role": "user"}
# ]
# Numeric default
echo '{"items":[1,2,3]}' | jq '.total // 0'
# Output: 0برنامج عملي: محلل سجل JSON
أصبح التسجيل المنظم بتنسيق JSON معيارًا في الأنظمة الحديثة. إليك برنامجًا نصيًا واقعيًا يقرأ ملف سجل JSON محددًا بأسطر جديدة، ويصفي إدخالات الأخطاء، وينسق ملخصًا مقروءًا للبشر.
الأنماط الأساسية المستخدمة:
-c(الإخراج المضغوط) — كائن JSON واحد لكل سطر، وهو مفيد للتمرير إلى حلقات shell--arg name value— يحقن متغير shell بوصفه وسيط سلسلة نصية إلى jqselectلتصفية مستوى السجل-rلإخراج السلاسل النصية الخام المناسبة لـecho
#!/usr/bin/env bash
# Parse newline-delimited JSON logs and report ERRORs
# Each log line: {"level":"ERROR","msg":"...","ts":"2024-01-15T10:23:00Z","svc":"auth"}
LOG_FILE="/var/log/app/app.log"
LEVEL="ERROR"
echo "=== $LEVEL entries in $LOG_FILE ==="
jq -r --arg lvl "$LEVEL" \
'select(.level == $lvl) | "[\(.ts)] [\(.svc)] \(.msg)"' \
"$LOG_FILE"
# Count errors per service
echo ""
echo "=== Error count by service ==="
jq -r --arg lvl "$LEVEL" \
'select(.level == $lvl) | .svc' "$LOG_FILE" \
| sort | uniq -c | sort -rnاختبار المعرفة: سلوك select() في jq
اختبر مدى فهمكم لكيفية عمل select() داخل مسار jq.
بالنظر إلى الأمر التالي:
echo '[{"name":"Alice","age":30},{"name":"Bob","age":17},{"name":"Carol","age":22}]' | jq '[.[] | select(.age >= 18) | .name]'ما الناتج؟
مراجعة الدرس: مسارات jq لتصفية JSON
لقد تناولتم الأدوات الأساسية في jq للتنقل داخل JSON وتصفيته من سطر الأوامر:
- الترميز النقطي (
.field،.a.b.c) يحدد الحقول من الكائنات - الوصول إلى المصفوفات (
.[0]،.[]) يفهرس المصفوفات ويمر على عناصرها - عامل الأنبوب (
|) يربط عوامل التصفية؛ إذ تعالج كل مرحلة جميع القيم الناتجة من المرحلة السابقة - select(cond) يصفي القيم، ويمرر فقط القيم التي يكون فيها الشرط صادقًا
- إنشاء الكائنات والمصفوفات (
{}،[]،map()) يعيد تشكيل البيانات في هياكل جديدة - العامل البديل (
//) يوفر قيمًا افتراضية للحقول الفارغة أو المفقودة - الخيار -r يزيل علامات الاقتباس عند إسناد القيم إلى متغيرات الصدفة؛ و--arg يحقن متغيرات الصدفة بأمان
- الاجتياز التكراري (
.. | .field?) يبحث في الأشجار المتداخلة بعمق عندما يكون المسار غير معروف
باستخدام هذه اللبنات، يمكنكم تحويل أي استجابة من واجهة JSON البرمجية أو ملف سجل أو ملف إعدادات إلى البيانات التي تحتاجها نصوصكم البرمجية بدقة — وكل ذلك من دون مغادرة الطرفية.
تعلم Bash مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 22
- الدروس
- 88
الأسئلة الشائعة
هل درس «تصفية JSON وتحديد عناصره باستخدام مسارات jq» مجاني؟
نعم — نص درس «تصفية JSON وتحديد عناصره باستخدام مسارات jq» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Linux Command Line & Bash Scripting Mastery، انتقل إلى CoddyKit PRO. تتضمن دورة Linux Command Line & Bash Scripting Mastery 4 دروس في المجموع.
ماذا ستتعلم في «تصفية JSON وتحديد عناصره باستخدام مسارات jq»؟
تنقّل بين الكائنات والمصفوفات المتداخلة باستخدام محددات jq والأنابيب ومرشّح select تتمرن على Linux Command Line & Bash Scripting Mastery مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Linux Command Line & Bash Scripting Mastery؟
لا تُشترط خبرة سابقة. Linux Command Line & Bash Scripting Mastery على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «تصفية JSON وتحديد عناصره باستخدام مسارات jq»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Linux Command Line & Bash Scripting Mastery هذا؟
نعم. كل درس في Linux Command Line & Bash Scripting Mastery يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تصفية JSON وتحديد عناصره باستخدام مسارات jq
- تحويل كائنات JSON وإنشاؤها باستخدام jq
- استهلاك REST APIs باستخدام curl وjq معًا
- تحرير ملفات إعداد YAML باستخدام yq