AzLearn

قراءة الملفات

Reading Files

مفهوم ~17 دقيقة

قراءة الملفات — Reading Files

قراءة الملفات في Bash تبدو بسيطة، لكنها مليئة بصيغ غير آمنة في الإنترنت. النمط الذي نريد حفظه هو: while IFS= read -r line; do ... done < "$file". هذه الصيغة تحافظ على السطر كما هو تقريباً. IFS= يمنع Bash من قص المسافات، و-r يمنع تفسير backslash.

لا تستخدم for line in $(cat file) لقراءة سطور ملف. هذه الصيغة تقسم النص إلى كلمات، لا سطور، وستكسر أي قيمة تحتوي مسافة. في السكربتات التي تتعامل مع logs أو CSV أو أسماء ملفات، هذا الخطأ شائع ومؤلم.

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

مثال بنص مدمج

script.sh

استخدمنا here-string هنا حتى يكون المثال مستقلاً داخل الدرس. عند قراءة ملف حقيقي، استبدل <<< "$lines" بـ< "$file_path":

while IFS= read -r line; do
    echo "$line"
done < "$file_path"

تحذير: السطر الأخير بدون سطر جديد

إذا انتهى الملف بنص بدون \n في النهاية، قد تتجاهله read. الحل الآمن:

while IFS= read -r line || [[ -n "$line" ]]; do
    echo "$line"
done < "$file_path"

|| [[ -n "$line" ]] يضمن معالجة السطر الأخير حتى لو لم يكن بعده سطر جديد. هذا خطأ شائع في ملفات تُنشأ بأوامر printf أو مخرجات أدوات معينة.

here-doc وتجريد المسافات <<-

الـ here-string (<<< "$var") مفيد للقيم القصيرة. للنصوص الأطول توجد صيغة here-doc:

while IFS= read -r line; do
    echo "$line"
done <<'EOF'
سطر أول
سطر ثانٍ
EOF

إذا أردت إزاحة محتوى الـ here-doc (indent) بمسافات بادئة لتتناسب مع الكود، استخدم <<- مع tabs (لا مسافات):

while IFS= read -r line; do
    echo "$line"
done <<-'EOF'
	سطر أول
	سطر ثانٍ
EOF

<<- يحذف tabs البادئة فقط من كل سطر. مفيد في دوال أو if حيث تريد المحافظة على التناسق البصري.

ملاحظة عن CSV

Bash يمكنها قراءة CSV بسيط جداً باستخدام IFS=, read -r name amount. لكن CSV الحقيقي قد يحتوي اقتباسات وفواصل داخل القيم. عندما تصل لهذه المرحلة، استخدم Python أو أداة مخصصة. Bash ممتازة للأشكال النصية البسيطة، وليست parser عاماً لكل تنسيق.

تحدي — Challenge