\ N và \ r được xử lý khác nhau như thế nào trên Linux và Windows?


22

Tôi nghĩ rằng \ndi chuyển kim xuống, và \rdi chuyển kim đến đầu của một dòng (căn lề trái)? Tôi không chắc chắn, mặc dù. Vì vậy, nếu tôi sai xin vui lòng sửa cho tôi ....

Dù sao, tôi đã nói rằng Windows và Linux xử lý newlinescarriage returnskhác nhau. Tôi muốn biết làm thế nào họ xử lý chúng khác nhau và một số nơi quan trọng cần nhớ. Cảm ơn đã trả lời.


Cho đến nay tôi biết điều đó \r\nlà ổn trong Windows nhưng \n\rkhông, và tôi nhớ điều đó bởi vì đó \r\nlà từ viết tắt của y tá đã đăng ký. Tôi cũng nghe rằng đó \nlà những gì mọi người sử dụng trong Linux và \rkhông được sử dụng một mình cho cùng một mục đích như \r\n. \rđược sử dụng trong MacOS thực sự cũ. Tôi đã không xác minh những sự thật, mặc dù.
千里 ち ゃ

4
Đừng gọi cho họ \r\n, vì cách \nxử lý tùy thuộc vào nơi bạn đang sử dụng. Tốt hơn để gọi cho họ CRLF.
Ignacio Vazquez-Abrams

Ignacio, những từ viết tắt không có ý nghĩa với tôi. Bạn gọi cái này là gì :/? OH ... LINE FEED và CARRIAGE TRẢ LẠI. Cảm ơn, sleske.
千里 ち ゃ

@ IgnacioVazquez-Abrams Không phải là giống hệt với LF? Trên bất kỳ biểu đồ ASCII nào, không phải là ký tự 13 = \ n = LF?
barlop

1
@barlop: Không có trong C khi xuất ra Windows.
Ignacio Vazquez-Abrams

Câu trả lời:


21

Tôi nghĩ rằng \ n di chuyển kim xuống và \ r di chuyển kim đến đầu một dòng (căn lề trái)? Tôi không chắc chắn, mặc dù

Điều này là đúng, ít nhiều, nhưng chủ yếu là một sự tò mò lịch sử. Ban đầu, linefeed (LF) đã được sử dụng để nâng cấp giấy bằng một dòng trên máy in và thiết bị đầu cuối bản cứng ( teleprinters ); trở lại vận chuyển (CR) trả lại đầu in đến đầu dòng.

Điều này có thể vẫn hoạt động trên các máy in hiện đại khi được sử dụng trong "chế độ văn bản", nhưng ngày nay không liên quan chút nào.

Dù sao, tôi đã nói rằng Windows và Linux xử lý các dòng mới và vận chuyển trở lại khác nhau.

Sự khác biệt đơn giản là: Các nhà thiết kế hệ điều hành phải chọn cách thể hiện sự bắt đầu của một dòng mới trong văn bản trong các tệp máy tính. Vì nhiều lý do lịch sử khác nhau, trong thế giới Unix / Linux, một nhân vật LF duy nhất đã được chọn làm điểm đánh dấu dòng mới; MS-DOS đã chọn CR + LF và Windows đã kế thừa điều này. Do đó, các nền tảng khác nhau sử dụng các quy ước khác nhau.

Trong thực tế, điều này ngày càng trở thành một vấn đề. Điểm đánh dấu dòng mới thực sự chỉ phù hợp với các pogram xử lý "văn bản thuần túy" và không có nhiều - nó chủ yếu chỉ ảnh hưởng đến mã nguồn chương trình, tệp cấu hình và một số tệp văn bản đơn giản có tài liệu. Ngày nay, hầu hết các chương trình xử lý các loại tệp này (trình soạn thảo, trình biên dịch, v.v.) có thể xử lý cả hai quy ước dòng mới, vì vậy việc bạn chọn loại nào không quan trọng.

Có một số trường hợp các công cụ nhấn mạnh vào "quy ước" dòng mới của họ (ví dụ: tập lệnh shell Unix không được sử dụng CR + LF), trong trường hợp đó bạn phải sử dụng đúng.


Cùng một dòng câu hỏi: các ngôn ngữ lập trình có nhận ra \n\r\ngiống nhau không? Ví dụ, nếu tôi được phân tích một file văn bản đã được chỉnh sửa trên máy tính của người khác và chứa cả hai phiên bản Linux và Windows của ngắt dòng, sẽ thực hiện một preg_matchcho \n\n\rđưa cho tôi kết quả khác nhau?
千里 ち ゃ

@ 千里 ち ゃ: Điều này hoàn toàn phụ thuộc vào ngôn ngữ lập trình, trình biên dịch, v.v. Tôi tin).
sleske

@ 千里 ち ゃ: Nếu bạn có câu hỏi về cách một số hệ thống / ngôn ngữ lập trình / công cụ biểu thức chính quy xử lý các quy ước dòng mới khác nhau, chỉ cần hỏi điều này như một câu hỏi riêng biệt.
sleske

bạn nên viết \ r \ n không sai cách như bạn đang làm. Đối với ngôn ngữ lập trình, họ sẽ có thể đọc các ký tự riêng lẻ và bạn lập trình viên có thể thấy ngôn ngữ nào được sử dụng trong đầu vào và lập trình viên cũng có thể làm như bạn muốn cho đầu ra. Giống như bạn có thể nói "Viết ABC theo sau bởi \ r \ r \ r \ n" bất cứ ký tự nào bạn muốn dán ở cuối! một số ký tự khác có thể không in được và không có đồ họa hoặc bất cứ thứ gì. Họ có thể có một số chức năng được xây dựng như println, và những gì họ sử dụng cho dòng mới của họ sẽ là cái này hoặc cái kia, nó không thể là cả hai.
barlop

.... + như đã đề cập, trong thực tế, bạn có thể viết bất kỳ dòng kết thúc nào bạn muốn ... mặc dù bạn có thể không thực hiện được một cách hiệu quả như với hàm println.
barlop

14

CR và LF

Mã tiêu chuẩn Mỹ để trao đổi thông tin (ASCII) đã xác định các ký tự điều khiển bao gồm CARRIAGE-RETURN (CR) và LINE-FEED (LF) được sử dụng để điều khiển vị trí in trên máy in theo cách tương tự với máy đánh chữ cơ học đi trước máy in máy tính sớm.

Nền tảng phụ thuộc

Trong Windows, trình phân tách dòng truyền thống trong các tệp văn bản là CR, theo sau là LF

Trong các hệ thống Apple Macintosh cũ (trước OSX), bộ tách dòng truyền thống trong các tệp văn bản là CR

Trong Unix và Linux, trình phân tách dòng truyền thống trong các tệp văn bản là LF.

\ n và \ r

Trong nhiều ngôn ngữ lập trình và kịch bản \ncó nghĩa là "dòng mới". Đôi khi (nhưng không phải luôn luôn) điều này có nghĩa là ký tự ASCII LINE-FEED (LF), như bạn nói, di chuyển con trỏ (hoặc vị trí in) xuống một dòng. Trong một máy in hoặc máy đánh chữ, điều này thực sự sẽ di chuyển giấy lên một dòng.

Lúc nào cũng vậy \r có nghĩa là ký tự ASCII CARRIAGE-RETURN (CR) có tên thực sự xuất phát từ máy đánh chữ cơ học, nơi có một phím quay trở lại vận chuyển khiến cho con lăn ("cỗ xe") mang giấy di chuyển sang bên phải, chạy bằng lò xo, như nó sẽ đi Do đó, thiết lập vị trí gõ hiện tại sang lề trái.

Lập trình

Trong một số ngôn ngữ lập trình \ncó thể có nghĩa là một chuỗi các ký tự phụ thuộc vào nền tảng kết thúc hoặc tách các dòng trong tệp văn bản. Ví dụ: trong Perl, print "\n"tạo ra một chuỗi các ký tự khác nhau trên Linux so với trên Windows.

Trong Java, thực hành tốt nhất, nếu bạn muốn sử dụng kết thúc dòng bản địa cho nền tảng chạy, không phải là để sử dụng \nhoặc \rở tất cả. Bạn nên sử dụng System.getProperty("line.separator"). Bạn nên sử dụng \n\rnơi bạn muốn LF và CR bất kể nền tảng (ví dụ như được sử dụng trong HTTP, FTP và các giao thức truyền thông Internet khác).

Unix stty

Trong shell Unix, sttylệnh có thể được sử dụng để khiến shell dịch giữa các quy ước khác nhau này. Ví dụ, stty -onlcrsẽ khiến shell sau đó dịch tất cả các LF đi ra CR CR.

Linux và OSX tuân theo các quy ước Unix

Tập tin văn bản

Các tập tin văn bản vẫn rất quan trọng và được sử dụng rộng rãi. Ví dụ, HTML và XML là các ví dụ về tệp văn bản. Hầu hết các giao thức Internet quan trọng, như HTTP, tuân theo các quy ước về tệp văn bản và bao gồm các thông số kỹ thuật cho các kết thúc dòng.

Máy in

Hầu hết các máy in khác với giá rẻ nhất, vẫn tôn trọng CR và LF. Trong thực tế, chúng là nền tảng cho các ngôn ngữ mô tả trang được sử dụng rộng rãi nhất - PCL và Postcript.


1
Lưu ý trên Java: Nói chung không đúng khi bạn "hoàn toàn không nên sử dụng \ n hoặc \ r". Chỉ là trong Java, "\ n" luôn là LF và "\ r" luôn là CR. Đây thể chỉ là những gì bạn muốn: Nếu bạn muốn một kiểu kết thúc dòng cụ thể, hãy sử dụng chúng; Nếu bạn rõ ràng muốn kết thúc dòng gốc của máy tính bạn đang chạy, thì hãy sử dụng line.separator. Nó thực sự phụ thuộc vào những gì bạn muốn.
sleske

Và BTW, println()tự động sử dụng line.separator, vì vậy nếu bạn muốn kết thúc dòng gốc, bạn có thể sử dụng println()(và nếu bạn cần một loại kết thúc dòng cụ thể nhất định, thì đừng sử dụng nó, nhưng sử dụng rõ ràng "\ n", v.v.).
sleske

@sleske: Điểm tốt. Tôi sẽ cập nhật câu trả lời của tôi cho phù hợp.
RedGrittyBrick

1
Có bất kỳ ngôn ngữ hoặc trình biên dịch nào \nlà ký tự điều khiển không phải là ASCII LF (không phải là các hệ thống dựa trên EBCDIC) không? Tôi đang đề cập đến những gì \ncó nghĩa là trong một chuỗi hoặc ký tự bằng chữ, không phải là tác động của việc gửi nó đến một tập tin hoặc thiết bị đầu ra.
Keith Thompson

1
@KeithThndry: Đối với Java: Có, \nluôn là mã ASCII (và Unicode) 10, bởi vì JLS nói rất rõ ràng (JLS 3.10.6, "Chuỗi thoát cho ký tự chuỗi và ký tự chuỗi" - Tôi đã kiểm tra :-)). Đối với các ngôn ngữ khác - câu hỏi hay.
sleske

4

Nói tóm lại, là cần thiết cho máy in, nhưng bây giờ các hệ điều hành làm điều đó hơi khác. Trong hầu hết các trường hợp, chỉ cần làm cả CR và LF bằng cách thực hiện \r\nvà trong hầu hết các trường hợp, điều này sẽ hoạt động tốt.


Có phải Linux chỉ bỏ qua \rhoặc nó gây ra một số loại thay đổi hành vi?
Aaron Franke
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.