تحويل النصوص في ويندوز إلى تنسيق لينكس

تحويل أحرف نهاية السطر الرئيسية عبر المنصات

Page content

تباينات في نهاية السطر بين أنظمة ويندوز ولينكس تسبب مشاكل في التنسيق، تحذيرات من جيت، وفشل في النصوص البرمجية. تغطي هذه الدليل الشامل طرق الكشف، التحويل، والوقاية من هذه المشاكل.

تحويل وثيقة من ويندوز إلى يونكس هذا الصورة الرائعة تم إنشاؤها بواسطة نموذج الذكاء الاصطناعي فلوكس 1 ديف.

فهم الاختلافات في نهاية السطر

تستخدم أنظمة التشغيل تقنيات مختلفة لتحديد نهاية السطر في الملفات النصية، مما يخلق تحديات في التطوير متعدد المنصات:

  • ويندوز: عودة الملف + تغذية السطر (\r\n أو CRLF، القيمة السداسية 0D 0A)
  • لينكس/يونكس: تغذية السطر فقط (\n أو LF، القيمة السداسية 0A)
  • نظام ماك كلاسيكي: عودة الملف فقط (\r أو CR، القيمة السداسية 0D)

ينبع هذا الاختلاف التاريخي من ميكانيكا آلات الطباعة. اعتمد ويندوز على تقنية CRLF من DOS، والتي حافظت على توافق مع آلات التيليتايب التي كانت تتطلب عودة الملف (الانتقال إلى بداية السطر) وتغذية السطر (التقدم في الورق).

المشاكل الشائعة الناتجة عن تباين نهاية السطر

1. فشل تنفيذ النصوص البرمجية

تفشل النصوص البرمجية ذات نهاية السطر من ويندوز مع أخطاء غامضة:

bash: ./script.sh: /bin/bash^M: bad interpreter: No such file or directory

يصبح الحرف ^M (عودة الملف) جزءًا من سطر التصحيح، مما يؤدي إلى فشل البحث عن المفسر.

2. تحذيرات جيت وضوضاء في الفرق

عند التزامن الملفات ذات نهاية السطر من ويندوز في جيت على لينكس، سترى:

warning: CRLF will be replaced by LF in file.txt.
The file will have its original line endings in your working directory

قد تظهر الفرق في جيت أن جميع الملفات قد تغيرت عندما تكون الاختلافات فقط في نهاية السطر، مما يخفي التغييرات الفعلية في الكود.

3. تأثير بصري في المحررات

المحررات النصية في لينكس التي لا تكتشف تلقائيًا نهاية السطر تظهر حرف ^M في نهاية السطر، مما يجعل الملفات صعبة القراءة والتحرير. هذا يصبح مشكلة خاصة في ملفات ماركداون الخاصة بهوغا حيث يمكن أن يُفسد تحليل المقدمة.

4. مشاكل في معالجة البيانات

قد تشمل النصوص البرمجية التي تحلل الملفات النصية عودة الملف في البيانات المستخرجة، مما يؤدي إلى فشل المقارنات والسلوك غير المتوقع في أنظمة معالجة البيانات.

الكشف عن نهاية السطر من ويندوز

قبل تحويل الملفات، حدد أي منها يحتاج إلى التحويل لتجنب التعديلات غير الضرورية.

الطريقة 1: استخدام أمر file

أفضل طريقة للكشف:

file content/post/my-post/index.md

أمثلة على المخرجات:

# نهاية السطر من ويندوز:
index.md: UTF-8 Unicode text, with CRLF line terminators

# نهاية السطر من لينكس:
index.md: UTF-8 Unicode text

# نهاية سطر مختلطة (مشكلة):
index.md: UTF-8 Unicode text, with CRLF, LF line terminators

الطريقة 2: الفحص البصري مع cat

عرض الحروف الخاصة:

cat -A filename.txt

تظهر الملفات من ويندوز حرف ^M$ في نهاية السطر، بينما تظهر الملفات من لينكس فقط $.

الطريقة 3: استخدام grep

البحث عن عودة الملف:

grep -r $'\r' content/post/2025/11/

هذا يحدد جميع الملفات التي تحتوي على CRLF في الدليل المحدد.

الطريقة 4: تحليل Hexdump

للتحليل التفصيلي على مستوى البايت:

hexdump -C filename.txt | head -n 20

ابحث عن التسلسل 0d 0a (CRLF) مقابل 0a (LF).

تحويل نهاية السطر من ويندوز إلى لينكس

توجد أدوات متعددة توفر تحويلًا موثوقًا مع اختلافات مختلفة في التوفر، والميزات، والأداء.

الحل 1: dos2unix (الموصى به)

أفضل حل موثوق ومزود بميزات متقدمة مصمم خصيصًا لتحويل نهاية السطر.

التثبيت

# Ubuntu/Debian
sudo apt install dos2unix

# Red Hat/CentOS/Fedora
sudo yum install dos2unix

# macOS (Homebrew)
brew install dos2unix

# Arch Linux
sudo pacman -S dos2unix

الاستخدام الأساسي

# تحويل ملف واحد (يُعدّل في المكان نفسه)
dos2unix filename.txt

# تحويل مع نسخ احتياطي (يُنشئ ملف .bak)
dos2unix -b filename.txt

# تحويل عدة ملفات
dos2unix file1.txt file2.txt file3.txt

# تحويل باستخدام النجم
dos2unix *.txt
dos2unix content/post/2025/11/*/index.md

خيارات متقدمة

# تشغيل تجريب (معاينة دون تعديل)
dos2unix --dry-run filename.txt

# الحفاظ على وقت التعديل
dos2unix -k filename.txt

# تحويل فقط إذا كانت نهاية السطر مختلفة
dos2unix -f filename.txt

# تحويل تلقائي
find . -name "*.md" -exec dos2unix {} \;

# تحويل جميع ملفات ماركداون في شجرة الملف
find content/post -type f -name "*.md" -exec dos2unix {} \;

معالجة دُفعة من مشاريع هوغا:

# تحويل جميع ملفات index.md في المشاريع لعام 2025
dos2unix content/post/2025/**/index.md

# تحويل جميع ملفات ماركداون باستثناء الدليل المحدد
find content/post -name "*.md" ! -path "*/drafts/*" -exec dos2unix {} \;

الحل 2: أمر sed

متوفر في جميع أنظمة يونكس بدون تثبيت إضافي، على الرغم من كونه أقل كفاءة في المجموعات الكبيرة.

# تحويل ملف واحد
sed -i 's/\r$//' filename.txt

# تحويل عدة ملفات باستخدام حلقة
for file in content/post/2025/11/*/index.md; do 
    sed -i 's/\r$//' "$file"
done

# تحويل مع نسخ احتياطي
sed -i.bak 's/\r$//' filename.txt

# تحويل تلقائي باستخدام find
find . -name "*.txt" -exec sed -i 's/\r$//' {} \;

ملاحظات مهمة

  • sed -i يُعدّل الملفات في المكان نفسه
  • على macOS، استخدم sed -i '' 's/\r$//' filename.txt
  • يُنشئ ملفات مؤقتة أثناء المعالجة
  • أبطأ من dos2unix في المجموعات الكبيرة

الحل 3: أمر tr

طريقة تعتمد على الأنابيب مفيدة في عمليات معالجة البيانات:

# تحويل أساسي (يتطلب توجيه الإخراج)
tr -d '\r' < input.txt > output.txt

# معالجة وتحويل في أنبوب
cat input.txt | tr -d '\r' | process_data.sh

# لا يمكن تعديل الملف في المكان نفسه - استخدم ملفًا مؤقتًا
tr -d '\r' < input.txt > temp.txt && mv temp.txt input.txt

المزايا

  • متوفر في جميع أنظمة يونكس
  • ممتاز لتدفق البيانات
  • يتكامل جيدًا مع الأنابيب

العيوب

  • لا يمكن تعديل الملف في المكان نفسه
  • يتطلب معالجة النسخ الاحتياطية يدويًا
  • أقل ملاءمة للعمليات الجماعية

الحل 4: استخدام awk

خيار بديل لمعالجة النصوص المعقدة:

awk '{sub(/\r$/,"")}1' input.txt > output.txt

# أو بشكل أكثر وضوحًا:
awk 'BEGIN{RS="\r\n"} {print}' input.txt > output.txt

جدول المقارنة

الأداة تعديل في المكان نفسه دفعات نسخ احتياطي السرعة التوفر
dos2unix سريعة يتطلب تثبيت
sed متوسطة مدمجة
tr سريعة مدمجة
awk متوسطة مدمجة

استراتيجيات الوقاية

الوقاية من نهاية السطر من ويندوز أكثر كفاءة من تحويل الملفات بشكل متكرر.

إعداد جيت

configure جيت لتحويل نهاية السطر تلقائيًا عبر المنصات.

الخيار 1: مستوى المشروع (.gitattributes)

أنشئ ملف .gitattributes في الجذر:

# اكتشاف تلقائي للملفات النصية وتحويلها إلى LF
* text=auto

# إعلان صريح للملفات النصية
*.md text
*.txt text
*.sh text eol=lf
*.py text eol=lf
*.go text eol=lf
*.js text eol=lf
*.json text eol=lf

# الملفات الثنائية
*.jpg binary
*.png binary
*.pdf binary

هذا يضمن نهاية السطر متسقة بغض النظر عن المنصة ومنع التحويلات غير الضرورية.

الخيار 2: إعداد المستخدم العالمي

configure سلوك جيت لجميع الملفات:

# لينكس/macOS: تحويل CRLF إلى LF عند التزامن، الاحتفاظ بـ LF دون تغيير
git config --global core.autocrlf input

# ويندوز: تحويل LF إلى CRLF عند الاسترجاع، CRLF إلى LF عند التزامن
git config --global core.autocrlf true

# تعطيل التحويل التلقائي (الاعتماد فقط على .gitattributes)
git config --global core.autocrlf false

الإعداد الموصى به

  • المطورون في لينكس/macOS: core.autocrlf input
  • المطورون في ويندوز: core.autocrlf true
  • جميع المشاريع: استخدم .gitattributes للتحكم الصريح

تحويل مشروع موجود

إذا كان مشروعك يحتوي بالفعل على نهاية سطر مختلطة:

# إزالة جميع الملفات من مؤشر جيت
git rm --cached -r .

# استعادة الملفات مع نهاية سطر مُعدَّلة
git reset --hard

# التزامن الملفات المُعدَّلة
git add .
git commit -m "Normalize line endings"

إعداد المحرر

configure المحررات لاستخدام نهاية السطر من لينكس بشكل افتراضي.

Visual Studio Code (settings.json)

{
  "files.eol": "\n",
  "files.encoding": "utf8",
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true
}

حدد حسب اللغة إذا لزم الأمر:

{
  "[markdown]": {
    "files.eol": "\n"
  }
}

Vim/Neovim (.vimrc)

set fileformat=unix
set fileformats=unix,dos

Emacs (.emacs أو init.el)

(setq-default buffer-file-coding-system 'utf-8-unix)

Sublime Text (Preferences.sublime-settings)

{
  "default_line_ending": "unix"
}

IDEs من JetBrains (الإعدادات → المحرر → أسلوب الكود)

  • مُفصِّل السطر: Unix وmacOS (\n)

EditorConfig

أنشئ ملف .editorconfig في الجذر للمشاريع لتوافق المحررات:

root = true

[*]
end_of_line = lf
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{sh,bash}]
end_of_line = lf

[*.bat]
end_of_line = crlf

تقوم معظم المحررات الحديثة بقبول إعدادات EditorConfig تلقائيًا، مما يضمن التوافق بين أعضاء الفريق الذين يستخدمون محررات مختلفة.

التلقائية والبرمجة

دمج فحص نهاية السطر في عمليات التطوير للكشف عن المشكلات مبكرًا.

Git Hook قبل التزامن

أنشئ .git/hooks/pre-commit:

#!/bin/bash
# فحص الملفات التي تحتوي على نهاية سطر CRLF

FILES=$(git diff --cached --name-only --diff-filter=ACM)
CRLF_FILES=""

for FILE in $FILES; do
    if file "$FILE" | grep -q "CRLF"; then
        CRLF_FILES="$CRLF_FILES\n  $FILE"
    fi
done

if [ -n "$CRLF_FILES" ]; then
    echo "خطأ: الملفات التالية تحتوي على نهاية سطر من ويندوز (CRLF):"
    echo -e "$CRLF_FILES"
    echo ""
    echo "تحويلها باستخدام: dos2unix <filename>"
    echo "أو configure محررك لاستخدام نهاية سطر من لينكس (LF)"
    exit 1
fi

exit 0

اجعله قابلًا للتنفيذ:

chmod +x .git/hooks/pre-commit

فحص في أنظمة CI

أضف إلى أنظمة CI (مثال GitHub Actions):

name: Check Line Endings

on: [push, pull_request]

jobs:
  check-line-endings:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Check for CRLF line endings
        run: |
          if git ls-files | xargs file | grep CRLF; then
            echo "Error: Files with CRLF line endings detected"
            exit 1
          fi          

نسخة قصيرة لتحويل نهاية السطر

أنشئ convert-line-endings.sh لصيانة المشروع:

#!/bin/bash
# تحويل جميع الملفات النصية في المشروع إلى نهاية سطر من لينكس

set -e

EXTENSIONS=("md" "txt" "sh" "py" "go" "js" "json" "yml" "yaml" "toml")

echo "تحويل نهاية السطر إلى صيغة لينكس..."

for ext in "${EXTENSIONS[@]}"; do
    echo "معالجة ملفات *.$ext..."
    find . -name "*.$ext" ! -path "*/node_modules/*" ! -path "*/.git/*" \
        -exec dos2unix {} \; 2>/dev/null || true
done

echo "التحويل مكتمل!"

تroubleshooting المشاكل الشائعة

المشكلة 1: لا يزال النص البرمجي يفشل بعد التحويل

الأعراض: النص البرمجي المحول باستخدام dos2unix لا يزال يظهر أخطاء في المفسر.

الحل: تحقق من تشفير الملف وعلامة BOM:

# تحقق من التشفير
file -i script.sh

# إزالة BOM إذا كان موجودًا
sed -i '1s/^\xEF\xBB\xBF//' script.sh

# تحقق من سطر التصحيح
head -n 1 script.sh | od -c

المشكلة 2: نهاية سطر مختلطة في ملف واحد

الأعراض: الملف يظهر كلاً من CRLF وLF.

الحل: تسوية باستخدام وضع dos2unix القسري:

dos2unix -f filename.txt

أو استخدام sed أكثر عدوانية:

# أولاً تحويل جميع CR إلى لا شيء، ثم تسوية
sed -i 's/\r//g' filename.txt

المشكلة 3: جيت لا يزال يظهر الملف كمُعدَّل

الأعراض: بعد تحويل نهاية السطر، يظهر جيت أن الملف مُعدَّل بدون تغييرات واضحة.

الحل: تحديث مؤشر جيت:

git add -u
git status

# إذا ظهرت ما زال، تحقق من إعدادات جيت
git config core.autocrlf

# تعطيل autocrlf مؤقتًا
git config core.autocrlf false
git add -u

المشكلة 4: فشل بناء هوغا بعد التحويل

الأعراض: يفشل هوغا في تحليل المقدمة بعد تحويل نهاية السطر.

الحل: تحقق من علامة BOM وصيغة المقدمة:

# إزالة BOM من ملفات ماركداون
find content -name "*.md" -exec sed -i '1s/^\xEF\xBB\xBF//' {} \;

# تحقق من صيغة YAML المقدمة
hugo --debug

المشكلة 5: لا توجد dos2unix متوفرة

الأعراض: النظام لا يحتوي على dos2unix ولا يمكن تثبيت البرامج.

الحل: استخدم دالة قابلة الحمل:

dos2unix_portable() {
    sed -i.bak 's/\r$//' "$1" && rm "${1}.bak"
}

dos2unix_portable filename.txt

الحالات الخاصة لهوغا

المواقع الثابتة لهوغا لها اعتبارات خاصة لنهائيات السطر، خصوصًا في الملفات المحتوى والتكوين.

تحويل محتوى هوغا

# تحويل جميع ملفات ماركداون المحتوى
find content -name "*.md" -exec dos2unix {} \;

# تحويل ملفات التكوين
dos2unix config.toml config.yaml

# تحويل ملفات الترجمة
find i18n -name "*.yaml" -exec dos2unix {} \;

# تحويل قوالب النماذج
find layouts -name "*.html" -exec dos2unix {} \;

التعامل مع المقدمة

المقدمة YAML حساسة بشكل خاص للمشاكل المتعلقة بنهائيات السطر. تأكد من الاتساق:

# تحقق من الملفات التي تحتوي على مقدمة
for file in content/post/**/index.md; do
    if head -n 1 "$file" | grep -q "^---$"; then
        file "$file"
    fi
done | grep CRLF

نصوص بناء هوغا

تأكد من أن نصوص البناء والنشر تستخدم نهاية سطر من لينكس:

dos2unix deploy.sh build.sh
chmod +x deploy.sh build.sh

اعتبارات الأداء

للمسائل الكبيرة التي تحتوي على آلاف الملفات، يهم أداء التحويل.

مقارنة الأداء

تحويل 1000 ملف ماركداون:

# dos2unix: ~2 ثانية
time find . -name "*.md" -exec dos2unix {} \;

# sed: ~8 ثوانٍ
time find . -name "*.md" -exec sed -i 's/\r$//' {} \;

# تحويل متوازي باستخدام dos2unix: ~0.5 ثانية
time find . -name "*.md" -print0 | xargs -0 -P 4 dos2unix

المعالجة المتوازية

استخدم GNU Parallel أو xargs لتحويل دفعات أسرع:

# باستخدام xargs مع تنفيذ متوازي
find . -name "*.md" -print0 | xargs -0 -P 8 dos2unix

# باستخدام GNU Parallel
find . -name "*.md" | parallel -j 8 dos2unix {}

أفضل الممارسات لتطوير متعدد المنصات

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

1. قائمة مراجعة إعداد المشروع

  • أضف .gitattributes مع إعلانات الملفات النصية
  • حدد core.autocrlf في وثائق الفريق
  • أضف .editorconfig في المشروع
  • أضف Hooks قبل التزامن للفحص
  • أضف سياسة نهاية السطر في README

2. ترحيب الفريق

يجب أن يconfigure أعضاء الفريق الجدد:

# استنساخ المشروع
git clone <repository>
cd <repository>

# configure جيت
git config core.autocrlf input  # لينكس/macOS
git config core.autocrlf true   # ويندوز

# تحقق من الإعداد
git config --list | grep autocrlf
cat .gitattributes

3. إرشادات مراجعة الكود

  • رفض الالتزامات التي تحتوي فقط على تغييرات نهاية السطر
  • استخدم git diff --ignore-cr-at-eol لمراجعات
  • تفعيل فحص نهاية السطر في CI/CD

4. الوثائق

أضف في README للمشروع:

## سياسة نهاية السطر

يستخدم هذا المشروع نهاية سطر من لينكس (LF) لجميع الملفات النصية.

**الإعداد:**

- لينكس/macOS: git config core.autocrlf input
- ويندوز: git config core.autocrlf true

**تحويل الملفات:**
dos2unix filename.txt

انظر إلى .gitattributes للحصول على إعدادات الملفات المحددة.

المواضيع المرتبطة لهوغا ولينكس

يعمل مع الملفات النصية عبر المنصات يتطلب فهم أدوات وعمليات متعددة. إليك مصادر للحصول على معلومات أعمق حول المواضيع المرتبطة:

المصادر الخارجية

هذه المصادر الموثوقة قدمت تفاصيل تقنية وممارسات مثالية لهذا المقال: