วิธีแปลงไฟล์ทั้งหมดในสาขาระบบไฟล์เป็นกลุ่มระหว่างรูปแบบตัวแบ่งบรรทัดของ Unix และ Windows


14

ทุกคนรู้ :-) ว่าในบรรทัดไฟล์ข้อความธรรมดาของ Windows จะถูกยกเลิกด้วย CR + LF และใน Unix & Linux - ด้วย LF เท่านั้น ฉันจะแปลงไฟล์โค้ดต้นฉบับทั้งหมดจากรูปแบบหนึ่งเป็นรูปแบบอื่นและสำรองอย่างรวดเร็วได้อย่างไร

คำตอบ:


17

ขึ้นอยู่กับว่า: หากไฟล์อยู่ภายใต้การควบคุมเวอร์ชันนี่อาจเป็นการตัดสินใจที่ไม่ก่อให้เกิดมลพิษต่อประวัติศาสตร์ Git มีตัวเลือกในการแปลงจุดสิ้นสุดของสายโดยอัตโนมัติเมื่อเช็คเอาต์

หากคุณไม่สนใจและต้องการแปลงอย่างรวดเร็วมีโปรแกรมเช่นfromdos/ todosและdos2unix/ unix2dosที่ทำเพื่อคุณ คุณสามารถใช้find: find . -type f -name '*.php' -exec dos2unix '{}' +.


7

มีโปรแกรมเฉพาะหลายโปรแกรมรวมถึง

  • dos2unixและunix2dosจากเครื่องมือdos2unix
  • todosและfromdosจากเครื่องมือtofrodos

เพียงเลือกเครื่องมือสำหรับทิศทางที่เหมาะสมและส่งชื่อของไฟล์เพื่อแปลงในบรรทัดคำสั่ง


หากคุณไม่มี แต่มี Linux หรือ Cygwin:

sed -i -e 's/\r\+$//' filename             # dos|unix -> unix
sed -i -e 's/\r*$/\r/' filename            # dos|unix -> dos

หากคุณมี Perl:

perl -i -pe 's/\r+$//' filename            # dos|unix -> unix
perl -i -pe 's/\r*$/\r/' filename          # dos|unix -> dos

ด้วยเครื่องมือ POSIX เท่านั้น (รวมถึง BusyBox) เพื่อไปจาก unix ไปยัง dos คุณจะต้องผ่านตัวอักษร CR อย่างแท้จริงในคำสั่ง sed

cr=$(echo | tr '\n' '\r')
sed -e "s/$cr*\$/$cr/" <filename >filename.dos
mv filename.dos filename

ในอีกทางหนึ่งคุณสามารถลบ CRs ทั้งหมด:

tr -d '\r' <filename >filename.dos
mv filename.dos filename

คุณสามารถใช้สัญลักษณ์แทนเพื่อแปลงไฟล์จำนวนมากในไดเรกทอรีเดียวกันในครั้งเดียวเช่น

sed -i -e 's/\r\+$//' *.txt

ในการแปลงไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยหากเชลล์ของคุณคือ zsh คุณสามารถใช้**/เช่น

sed -i -e 's/\r\+$//' **/*.txt

คุณสามารถใช้**/ใน bash ≥4 แต่คุณต้องเรียกใช้shopt -s globstarก่อน (คุณสามารถใส่บรรทัดนี้ในของคุณ~/.bashrc) คุณสามารถใช้**/ใน ksh93 แต่คุณจำเป็นต้องเรียกใช้set -o globstarครั้งแรก ~/.kshrc(คุณสามารถใส่บรรทัดนี้ในของคุณ

หากคุณสามารถใช้เครื่องมือที่ต้องมีการเปลี่ยนเส้นทางให้ใช้การforวนซ้ำ

for x in *.txt; do
  tr -d '\r' <"$x" >"$x.dos"
  mv -- "$x.dos" "$x"
done

หากคุณไม่มี**/หรือต้องการการจับคู่ที่ซับซ้อนยิ่งขึ้นเพื่อเลือกไฟล์ที่จะแปลงให้ใช้findคำสั่ง นี่เป็นตัวอย่าง Linux / Cygwin ซึ่งจะแปลงไฟล์ทั้งหมดภายใต้ไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยซ้ำยกเว้นสำหรับไฟล์ที่เรียกว่าและภายใต้ไดเรกทอรีย่อยที่เรียกว่า.obin

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sed -i -e 's/\r\+$//' {} +

นี่คือตัวอย่าง POSIX เราบอกfindให้เริ่มเชลล์ที่สามารถทำการเปลี่ยนเส้นทางที่จำเป็น

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       tr -d '\r' <"$0" >"$0.dos"
       mv -- "$0.dos" "$0"
' {} \;

คุณสามารถทำให้findวิธีนี้เร็วขึ้นเล็กน้อยโดยใช้รหัสที่ซับซ้อนมากขึ้นโดยใช้การวนซ้ำในคำสั่งเชลล์

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       for x; do
         tr -d '\r' <"$x" >"$x.dos"
         mv -- "$x.dos" "$x"
       done
' _ {} +

2

winscpจะทำการแปลงโดยอัตโนมัติเช่นกัน

หากไฟล์ของคุณอยู่ในไดเรกทอรีเดียวกัน:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*

คุณช่วยอธิบายเพิ่มเติมอีกเล็กน้อยได้อย่างไรถึงจะประสบความสำเร็จผ่าน WinSCP ได้หรือไม่
harish sharma

@harishsharma ฉันเพิ่มลิงก์ obove ไปยัง "บอกอย่างนั้น"
นิลส์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.