ทุกคนรู้ :-) ว่าในบรรทัดไฟล์ข้อความธรรมดาของ Windows จะถูกยกเลิกด้วย CR + LF และใน Unix & Linux - ด้วย LF เท่านั้น ฉันจะแปลงไฟล์โค้ดต้นฉบับทั้งหมดจากรูปแบบหนึ่งเป็นรูปแบบอื่นและสำรองอย่างรวดเร็วได้อย่างไร
ทุกคนรู้ :-) ว่าในบรรทัดไฟล์ข้อความธรรมดาของ Windows จะถูกยกเลิกด้วย CR + LF และใน Unix & Linux - ด้วย LF เท่านั้น ฉันจะแปลงไฟล์โค้ดต้นฉบับทั้งหมดจากรูปแบบหนึ่งเป็นรูปแบบอื่นและสำรองอย่างรวดเร็วได้อย่างไร
คำตอบ:
ขึ้นอยู่กับว่า: หากไฟล์อยู่ภายใต้การควบคุมเวอร์ชันนี่อาจเป็นการตัดสินใจที่ไม่ก่อให้เกิดมลพิษต่อประวัติศาสตร์ Git มีตัวเลือกในการแปลงจุดสิ้นสุดของสายโดยอัตโนมัติเมื่อเช็คเอาต์
หากคุณไม่สนใจและต้องการแปลงอย่างรวดเร็วมีโปรแกรมเช่นfromdos
/ todos
และdos2unix
/ unix2dos
ที่ทำเพื่อคุณ คุณสามารถใช้find
: find . -type f -name '*.php' -exec dos2unix '{}' +
.
มีโปรแกรมเฉพาะหลายโปรแกรมรวมถึง
เพียงเลือกเครื่องมือสำหรับทิศทางที่เหมาะสมและส่งชื่อของไฟล์เพื่อแปลงในบรรทัดคำสั่ง
หากคุณไม่มี แต่มี 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 ซึ่งจะแปลงไฟล์ทั้งหมดภายใต้ไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยซ้ำยกเว้นสำหรับไฟล์ที่เรียกว่าและภายใต้ไดเรกทอรีย่อยที่เรียกว่า.o
bin
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
' _ {} +