\ n และ \ r จัดการกับ Linux และ Windows แตกต่างกันอย่างไร


22

ฉันคิด \nย้ายเข็มลงแล้ว\rเลื่อนเข็มไปที่จุดเริ่มต้นของเส้น (จัดแนวซ้าย) แต่ฉันไม่แน่ใจ ดังนั้นถ้าฉันผิดโปรดแก้ไขฉัน ....

อย่างไรก็ตามฉันบอกว่า Windows และ Linux จัดการnewlinesและcarriage returnsแตกต่างกัน ฉันต้องการทราบว่าพวกเขาจัดการกับพวกเขาแตกต่างกันอย่างไรและบางแห่งที่สำคัญที่ต้องจำ ขอบคุณสำหรับคำตอบ.


จนถึงตอนนี้ฉันรู้ว่า\r\nไม่เป็นไรใน Windows แต่\n\rไม่ได้และฉันจำได้ว่าเพราะ\r\nเป็นตัวย่อสำหรับพยาบาลที่ลงทะเบียน ฉันยังได้ยินว่า\nเป็นสิ่งที่คนใช้ใน Linux และไม่ได้ใช้เพียงอย่างเดียวเพื่อวัตถุประสงค์เดียวกันเป็น \r ใช้ใน MacOS รุ่นเก่าจริงๆ แต่ฉันยังไม่ได้ตรวจสอบข้อเท็จจริงเหล่านี้ \r\n\r
千里ちゃん

4
อย่าเรียกพวกเขา\rและ\nเนื่องจากวิธีการที่\nมีการจัดการขึ้นอยู่กับที่คุณใช้มัน ดีกว่าที่จะเรียกพวกเขาและCR LF
Ignacio Vazquez-Abrams

อิกนาชิโอคำย่อเหล่านั้นไม่มีความหมายสำหรับฉัน คุณเรียกสิ่งนี้ว่าอะไร: / โอ้ ... สายป้อนอาหารและผลตอบแทนการเดินทาง ขอบคุณ sleske
千里ちゃん

@ IgnacioVazquez-Abrams \ n ไม่เหมือนกับ LF ใช่ไหม ในแผนภูมิ ASCII ใด ๆ ไม่ใช่อักขระ 13 = \ n = LF หรือ
barlop

1
@barlop: ไม่อยู่ใน C เมื่อแสดงผลใน Windows
Ignacio Vazquez-Abrams

คำตอบ:


21

ฉันคิดว่า \ n ย้ายเข็มลงและ \ r ย้ายเข็มไปที่จุดเริ่มต้นของบรรทัด (จัดชิดซ้าย) หรือไม่ แต่ฉันไม่แน่ใจ

สิ่งนี้เป็นจริงมากหรือน้อย แต่ส่วนใหญ่เป็นความอยากรู้ทางประวัติศาสตร์ แต่เดิม linefeed (LF) ถูกนำมาใช้เพื่อความก้าวหน้าของกระดาษโดยหนึ่งบรรทัดบนเครื่องพิมพ์และขั้วกระดาษ ( teleprinters ); carriage return (CR) คืนหัวพิมพ์กลับไปที่จุดเริ่มต้นของบรรทัด

สิ่งนี้อาจยังคงใช้งานได้กับเครื่องพิมพ์สมัยใหม่เมื่อใช้ใน "โหมดข้อความ" แต่มีความเกี่ยวข้องน้อยมากในปัจจุบัน

อย่างไรก็ตามมีคนบอกฉันว่า Windows และ Linux จัดการกับการขึ้นบรรทัดใหม่และการรับขนกลับแตกต่างกัน

ความแตกต่างคือง่ายๆ: นักออกแบบระบบปฏิบัติการต้องเลือกวิธีแสดงบรรทัดใหม่ในข้อความในไฟล์คอมพิวเตอร์ ด้วยเหตุผลทางประวัติศาสตร์ที่หลากหลายในโลกของ Unix / Linux ตัวอักษร LF ตัวเดียวได้รับเลือกให้เป็นเครื่องหมายขึ้นบรรทัดใหม่ MS-DOS เลือก CR + LF และ Windows สืบทอดสิ่งนี้ ดังนั้นแพลตฟอร์มที่แตกต่างกันจึงใช้การประชุมที่แตกต่างกัน

ในทางปฏิบัติสิ่งนี้กำลังมีปัญหาน้อยลงเรื่อย ๆ เครื่องหมายขึ้นบรรทัดใหม่มีความเกี่ยวข้องกับ pograms ที่ประมวลผล "ข้อความธรรมดา" เท่านั้นและมีไม่มาก - โดยส่วนใหญ่จะมีผลเฉพาะกับซอร์สโค้ดโปรแกรมไฟล์กำหนดค่าและไฟล์ข้อความทั่วไปที่มีเอกสารประกอบ ทุกวันนี้โปรแกรมส่วนใหญ่ที่จัดการกับไฟล์ประเภทนี้ (บรรณาธิการ, คอมไพเลอร์และอื่น ๆ ) สามารถจัดการกับข้อตกลงการขึ้นบรรทัดใหม่ดังนั้นจึงไม่สำคัญว่าคุณจะเลือกแบบใด

มีบางกรณีที่เครื่องมือยืนยันในการขึ้นบรรทัดใหม่ "ของพวกเขา" (เช่นสคริปต์ Unix shell จะต้องไม่ใช้ CR + LF) ซึ่งในกรณีนี้คุณต้องใช้อย่างถูกต้อง


บรรทัดคำถามที่เหมือนกัน: ภาษาการเขียนโปรแกรมรู้จัก\n\rและ\nเหมือนกันหรือไม่? ตัวอย่างเช่นถ้าผมแยกไฟล์ข้อความที่ได้รับการแก้ไขในเครื่องคอมพิวเตอร์ของคนอื่นและมีทั้ง Linux และ Windows รุ่นแบ่งบรรทัดจะดำเนินการpreg_matchสำหรับการ\nและ\n\rให้ฉันผลแตกต่างกันอย่างไร
千里ちゃん

@ 千里ちゃん: ทั้งหมดนี้ขึ้นอยู่กับภาษาการเขียนโปรแกรมคอมไพเลอร์และอื่น ๆ โดยเฉพาะถ้าคุณใช้ regexes มันจะขึ้นอยู่กับเอ็นจิ้น regex ที่คุณใช้ ฉันเชื่อ).
sleske

@ 千里ちゃん: หากคุณมีคำถามว่าระบบ / ภาษาการเขียนโปรแกรม / กลไกการแสดงออกปกติจัดการกับการขึ้นบรรทัดใหม่ที่แตกต่างกันเพียงแค่ถามคำถามนี้เป็นคำถามแยกต่างหาก
sleske

คุณควรเขียน \ r \ n ไม่ใช่วิธีที่ผิดเหมือนที่เป็นอยู่ สำหรับภาษาการเขียนโปรแกรมพวกเขาจะสามารถอ่านอักขระแต่ละตัวและคุณโปรแกรมเมอร์สามารถดูว่ามีการใช้อะไรในอินพุตและโปรแกรมเมอร์ก็สามารถทำได้ตามที่คุณต้องการสำหรับผลลัพธ์ อย่างที่คุณสามารถพูดว่า "เขียน ABC ตามด้วย \ r \ r \ r \ n" ตัวละครอะไรก็ตามที่คุณต้องการติดท้าย! อักขระอื่นบางตัวอาจไม่สามารถพิมพ์ได้และไม่มีกราฟิกหรืออะไรก็ตาม พวกเขาอาจมีฟังก์ชั่นในตัวเช่น println และสิ่งที่พวกเขาใช้สำหรับบรรทัดใหม่ของพวกเขาจะเป็นหนึ่งหรืออื่น ๆ มันไม่สามารถเป็นได้ทั้ง
barlop

@ 千里ちゃんและภาษาการเขียนโปรแกรมบางอย่างอาจช่วยให้คุณเลือกว่า lnie ลงท้ายด้วยการตั้งค่าในหนึ่งในฟังก์ชั่นที่สร้างขึ้นของพวกเขาดังนั้นแม้ในฟังก์ชั่นในตัวคุณสามารถ .. ในทางทฤษฎี + ตามที่กล่าวไว้ในทางปฏิบัติคุณสามารถเขียนสิ่งใดก็ตามที่ลงท้ายด้วยบรรทัดที่คุณต้องการ ... แม้ว่าคุณอาจไม่สามารถทำได้อย่างมีประสิทธิภาพเหมือนกับฟังก์ชั่น println
barlop

14

CR และ LF

รหัสมาตรฐานอเมริกันสำหรับการแลกเปลี่ยนข้อมูล (ASCII) กำหนดอักขระควบคุมรวมถึง CARRIAGE-RETURN (CR) และ LINE-FEED (LF) ที่ใช้ (และยังคงเป็น) ที่ใช้ในการควบคุมตำแหน่งการพิมพ์บนเครื่องพิมพ์ในลักษณะที่คล้ายคลึงกับ เครื่องพิมพ์ดีดเชิงกลที่นำหน้าเครื่องพิมพ์คอมพิวเตอร์รุ่นแรก

การพึ่งพาแพลตฟอร์ม

ใน Windows ตัวแยกบรรทัดแบบดั้งเดิมในไฟล์ข้อความคือ CR ตามด้วย LF

ระบบ Apple Macintosh เก่า (ก่อน OSX) ตัวแยกบรรทัดแบบดั้งเดิมในไฟล์ข้อความคือ CR

ใน Unix และ Linux ตัวแยกบรรทัดแบบดั้งเดิมในไฟล์ข้อความคือ LF

\ n และ \ r

ในการเขียนโปรแกรมและภาษาสคริปต์จำนวนมาก\nหมายถึง "บรรทัดใหม่" บางครั้ง (แต่ไม่เสมอไป) นี่หมายถึงอักขระ ASCII LINE-FEED (LF) ซึ่งตามที่คุณพูดจะย้ายเคอร์เซอร์ (หรือตำแหน่งการพิมพ์) ลงหนึ่งบรรทัด ในเครื่องพิมพ์หรือเครื่องพิมพ์ดีดสิ่งนี้จะเลื่อนกระดาษขึ้นหนึ่งบรรทัด

อย่างสม่ำเสมอ \rหมายถึงอักขระ ASCII ผลตอบแทนการขนส่ง (CR) ซึ่งมีชื่อจริงมาจากเครื่องพิมพ์ดีดกลที่มีความสำคัญผลตอบแทนการขนส่งที่ก่อให้เกิดลูกกลิ้ง ( "สายการบิน") ที่ดำเนินกระดาษที่จะย้ายไปทางขวาขับเคลื่อนโดยฤดูใบไม้ผลิ เท่าที่มันจะไป ดังนั้นการตั้งค่าตำแหน่งการพิมพ์ปัจจุบันเป็นระยะขอบซ้าย

การเขียนโปรแกรม

ในภาษาการเขียนโปรแกรมบางภาษา\nอาจหมายถึงลำดับของอักขระขึ้นอยู่กับแพลตฟอร์มที่สิ้นสุดหรือแยกบรรทัดในไฟล์ข้อความ ตัวอย่างเช่นใน Perl print "\n"สร้างลำดับอักขระที่แตกต่างบน Linux มากกว่าบน Windows

ใน Java แนวทางปฏิบัติที่ดีที่สุดหากคุณต้องการใช้ปลายสายแบบเนทีฟสำหรับแพลตฟอร์มรันไทม์ไม่ควรใช้\nหรือไม่ใช้\rเลย System.getProperty("line.separator")คุณควรใช้ คุณควรใช้\nและ\rตำแหน่งที่คุณต้องการ LF และ CR โดยไม่คำนึงถึงแพลตฟอร์ม (เช่นที่ใช้ใน HTTP, FTP และโปรโตคอลการสื่อสารทางอินเทอร์เน็ตอื่น ๆ )

Unix stty

ในเชลล์ Unix sttyคำสั่งสามารถใช้เพื่อทำให้เชลล์แปลระหว่างการประชุมที่หลากหลายเหล่านี้ ตัวอย่างเช่นstty -onlcrจะทำให้เชลล์แปล LFs ขาออกทั้งหมดเป็น CR LF ในภายหลัง

Linux และ OSX ปฏิบัติตามข้อตกลง Unix

ไฟล์ข้อความ

ไฟล์ข้อความยังคงมีความสำคัญอย่างมากและใช้กันอย่างแพร่หลาย ตัวอย่างเช่น HTML และ XML เป็นตัวอย่างของไฟล์ข้อความ โพรโทคอลอินเทอร์เน็ตที่สำคัญส่วนใหญ่เช่น HTTP เป็นไปตามข้อกำหนดของไฟล์ข้อความและมีข้อกำหนดสำหรับการวางสาย

เครื่องพิมพ์

เครื่องพิมพ์ส่วนใหญ่นอกเหนือจากที่ถูกที่สุดยังเคารพ CR และ LF ในความเป็นจริงมันเป็นพื้นฐานของภาษาคำอธิบายหน้าที่ใช้กันอย่างแพร่หลาย - PCL และ Postscript


1
หมายเหตุเกี่ยวกับ Java: โดยทั่วไปไม่จริงที่คุณควร "ไม่ใช้ \ n หรือ \ r เลย" เป็นเพียงแค่ใน Java, "\ n" เสมอ LF และ "\ r" เสมอ CR นี่อาจเป็นสิ่งที่คุณต้องการ: หากคุณต้องการรูปแบบการสิ้นสุดบรรทัดเฉพาะให้ใช้ ถ้าคุณต้องการเส้นพื้นเมืองสิ้นสุดของคอมพิวเตอร์ที่คุณกำลังทำงานอยู่บนอย่างชัดเจนแล้วline.separatorการใช้งาน มันขึ้นอยู่กับสิ่งที่คุณต้องการจริงๆ
sleske

และ BTW println()จะใช้งานโดยอัตโนมัติline.separatorดังนั้นหากคุณต้องการการสิ้นสุดบรรทัดแบบเนทีฟคุณสามารถใช้println()(และหากคุณต้องการการสิ้นสุดบรรทัดเฉพาะประเภทใดประเภทหนึ่งโดยเฉพาะอย่าใช้ แต่ใช้ "\ n" ฯลฯ อย่างชัดเจน)
sleske

@sleske: คะแนนดี ฉันจะอัปเดตคำตอบของฉันตาม
RedGrittyBrick

1
มีภาษาหรือคอมไพเลอร์ใดบ้างที่\nมีอักขระควบคุมนอกเหนือจาก ASCII LF (นอกเหนือจากระบบที่ใช้ EBCDIC)? ฉันหมายถึงสิ่งที่มีความ\nหมายในสตริงหรือตัวอักษรตัวอักษรไม่ให้ผลของการส่งไปยังไฟล์หรืออุปกรณ์ส่งออก
Keith Thompson

1
@ KeithThompson: สำหรับ Java: ใช่\nเสมอ ASCII (และ Unicode) รหัส 10 เพราะ JLS พูดอย่างชัดเจน (JLS 3.10.6, "Escape Sequences สำหรับตัวอักษรและสตริงตัวอักษร" - ฉันตรวจสอบแล้ว :-)) สำหรับภาษาอื่น ๆ - คำถามที่ดี
sleske

4

กล่าวโดยย่อคือสิ่งที่จำเป็นสำหรับเครื่องพิมพ์ แต่ตอนนี้ระบบปฏิบัติการต่างกันเล็กน้อย ในกรณีส่วนใหญ่มันเป็นเรื่องปกติที่จะทำทั้ง CR และ LF โดยทำ\r\nและในกรณีส่วนใหญ่มันจะทำงานได้ดี


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