Làm cách nào để chuyển đổi hàng loạt tất cả các tệp trong một nhánh hệ thống tệp giữa định dạng ngắt dòng Unix và Windows?


14

Mọi người đều biết :-) rằng các dòng tệp văn bản thuần trong Windows được kết thúc bằng CR + LF và trong Unix & Linux - chỉ với LF. Làm cách nào tôi có thể nhanh chóng chuyển đổi tất cả các tệp mã nguồn của mình từ định dạng này sang định dạng khác và quay lại?

Câu trả lời:


17

Điều đó phụ thuộc: nếu các tệp nằm dưới sự kiểm soát phiên bản, đây có thể là một quyết định gây ô nhiễm lịch sử khá phổ biến. Git có tùy chọn tự động chuyển đổi kết thúc dòng khi thanh toán.

Nếu bạn không quan tâm và muốn nhanh chóng chuyển đổi, có những chương trình như fromdos/ todosdos2unix/ unix2doslàm điều này cho bạn. Bạn có thể sử dụng find: find . -type f -name '*.php' -exec dos2unix '{}' +.


7

Có một số chương trình dành riêng, bao gồm

  • dos2unixunix2dostừ các công cụ dos2unix
  • todosfromdostừ các công cụ tofrodos

Chỉ cần chọn công cụ cho hướng thích hợp và chuyển tên của các tệp để chuyển đổi trên dòng lệnh.


Nếu bạn không có, nhưng có Linux hoặc Cygwin:

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

Nếu bạn có perl:

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

Chỉ với các công cụ POSIX (bao gồm BusyBox), để chuyển từ unix sang dos, bạn sẽ cần truyền ký tự CR theo nghĩa đen trong lệnh sed.

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

Theo hướng khác, bạn chỉ cần xóa tất cả các CR:

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

Bạn có thể sử dụng ký tự đại diện để chuyển đổi nhiều tệp trong cùng một thư mục, ví dụ:

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

Để chuyển đổi tất cả các tệp trong thư mục hiện tại và thư mục con của nó, nếu shell của bạn là zsh, bạn có thể sử dụng **/, vd

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

Bạn có thể sử dụng **/trong bash ≥4, nhưng bạn cần chạy shopt -s globstartrước (bạn có thể đặt dòng này vào ~/.bashrc). Bạn có thể sử dụng **/trong ksh93, nhưng bạn cần chạy set -o globstartrước (bạn có thể đặt dòng này vào ~/.kshrc.

Nếu bạn chỉ có thể sử dụng các công cụ yêu cầu chuyển hướng, hãy sử dụng forvòng lặp.

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

Nếu bạn không có **/hoặc cần kết hợp phức tạp hơn để chọn tệp nào cần chuyển đổi, hãy sử dụng findlệnh. Đây là một ví dụ Linux / Cygwin chuyển đổi tất cả các tệp trong thư mục hiện tại và các thư mục con của nó theo cách đệ quy, ngoại trừ các tệp được gọi .ovà dưới các thư mục con được gọi bin.

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

Đây là một ví dụ POSIX. Chúng tôi nói findđể bắt đầu một lớp vỏ có thể thực hiện chuyển hướng cần thiết.

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

Bạn có thể làm cho findphương thức nhanh hơn một chút, với chi phí của mã phức tạp hơn, bằng cách sử dụng một vòng lặp trong lệnh shell.

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

wincp cũng sẽ tự động chuyển đổi, nếu được nói như vậy .

Nếu các tệp của bạn nằm trong cùng một thư mục:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*

Bạn có thể vui lòng mô tả thêm một chút, làm thế nào để đạt được thông qua WinSCP?
harish sharma

@harishsharma Tôi đã thêm một liên kết phía trên để "nói như vậy".
Nils
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.