เหตุผลสำหรับ \ r และ \ n หมายถึงสิ่งต่าง ๆ ในคำสั่ง s?


13

เราทุกคนรู้ว่าเมื่อค้นหา\nคือขึ้นบรรทัดใหม่และ\rเป็น carriage return ( ^M) แต่เมื่อแทนที่\rเป็นขึ้นบรรทัดใหม่ในขณะที่\nเป็นโมฆะ null ( ^@)

ต้นกำเนิดของความไม่สมดุลนี้คืออะไร? ระบุว่าพฤติกรรมนี้เป็น ... แปลกประหลาดที่จะพูดน้อย (และค่อนข้างต่อต้านเมื่อคุณได้รับมันผิดครั้งแรก) ฉันคาดว่าจะมีเหตุผลทางประวัติศาสตร์ที่แปลกประหลาด

(บังเอิญมีวิธี "แก้ไข" พฤติกรรมนี้และทำให้บางสิ่งบางอย่างง่ายขึ้นหรือไม่)

คำตอบ:


10

ในระดับพื้นฐานที่สุดที่มีอยู่แล้วความไม่สมดุลระหว่างการค้นหาและแทนที่ส่วนของ:substituteเพราะอดีตคือการแสดงออกปกติและหลังเป็นข้อความที่มีการเพิ่มเติมเฉพาะลำดับหนี นี่เป็นเพียงการเน้นโดยสัญชาตญาณที่คุณมีเกี่ยวกับความ\nหมาย

ยกตัวอย่างเช่นพิจารณาว่าในการค้นหาไม่ตรงกับตัวอักษร\n \nมันตรงกับปลายสาย (EOL) ลำดับไบต์ซึ่งอาจจะเป็น\r, \r\nหรือเพียงแค่\nขึ้นอยู่กับ'fileformat'ของบัฟเฟอร์

เท่าที่ทำไม\rใช้ในการหมายถึง "แทรก EOL" มีประวัติบางอย่างอยู่เบื้องหลัง Vi ไม่มีวิธีจัดการกับ NUL ไบต์ในไฟล์ Vim ได้รับการปรับปรุงให้ดีขึ้นโดยการแทนที่ NUL ไบต์ด้วย NL ไบต์ภายใน (เนื่องจากสตริง C เป็นตัวคั่น NUL)

รายละเอียดการใช้งานนี้รั่วไหลไปสู่พฤติกรรมของ:substituteเนื่องจาก\nในการแทนที่จะถูกแทรกลงในการเป็นตัวแทนภายในของบรรทัดนั้นซึ่งจะใช้เพื่อระบุ NUL ไบต์ \rแทรก EOL และแบ่งสายภายในเป็นสองส่วน Vim ไม่ได้จัดเก็บ EOL ไบต์ในหน่วยความจำแทน (de) การทำให้เป็นอนุกรมเมื่อทำการอ่าน / เขียนบัฟเฟอร์

ไม่สามารถเปลี่ยนแปลงได้ในขณะนี้โดยไม่ทำลายสคริปต์จำนวนมากและหน่วยความจำกล้ามเนื้อของผู้ใช้จำนวนมาก :help sub-replace-specialโชคดีที่มันบันทึกไว้ใน


6

NULไบต์เป็นเทอร์มิสตริงใน C, และด้วยเหตุผลนี้เป็นกลุ่มที่ใช้การประชุมนี้ที่อธิบายไว้ในคู่มือที่:h NL-used-for-Nul:

<Nul> อักขระในไฟล์ถูกเก็บเป็น <NL> ในหน่วยความจำ ในหน้าจอจะแสดงเป็น "^ @" การแปลเสร็จสิ้นเมื่ออ่านและเขียนไฟล์ ในการจับคู่ <Nul> กับรูปแบบการค้นหาคุณสามารถป้อน CTRL- @ หรือ "CTRL-V 000" นี่อาจเป็นสิ่งที่คุณคาดหวัง ภายในตัวละครจะถูกแทนที่ด้วย <NL> ในรูปแบบการค้นหา สิ่งที่ผิดปกติคือการพิมพ์ CTRL-V CTRL-J ยังแทรก <NL> ด้วยดังนั้นการค้นหา <Nul> ในไฟล์ {Vi ไม่สามารถจัดการอักขระ <Nul> ในไฟล์ได้เลย}

อนุสัญญานี้มีการแพร่กระจายไปยัง:s/.../.../คำสั่ง แต่ไม่รวมถึงsubstitute()ฟังก์ชัน \rและ\nในสายแทนที่ในการsubstitute()โทรเก็บความหมายดั้งเดิมของพวกเขา

ฉันไม่คิดว่ามีเหตุผลที่ลึกซึ้งสำหรับพฤติกรรมทั้งสองอย่าง viเป็นกลุ่มที่มีการพัฒนาเพียงแค่อินทรีย์ไปจากเดิม ไม่เคยมีพิมพ์เขียวขนาดใหญ่สำหรับมันคุณสมบัติถูกซ้อนทับกันด้วยความพยายามเพียงเล็กน้อยในการจัดระเบียบ


0

Vi Vi อื่น ๆ ไม่สนับสนุน\rหรือ\n(เหมือนเครื่องหมายแบ็กสแลชและตัวอักษรจริง) ในการทดแทน แต่พฤติกรรมของจริง^M( CTRL-V Enter) หมายถึงการแยกบรรทัดออกเป็นสองบรรทัดคือพฤติกรรมมาตรฐาน :

การป้อน <carriage-return> ในrepl (ซึ่งจำเป็นต้องมีการหลบหนี <backslash> ในโหมดexและการหลีกเลี่ยง <control> -V ในโหมดเปิดหรือโหมดvi ) จะแยกบรรทัดที่จุดนั้นสร้างบรรทัดใหม่ในบัฟเฟอร์แก้ไข . <carriage-return> จะถูกทิ้ง

ในไฟล์เก็บถาวรประวัติ Unix เวอร์ชันแรกของ BSD ex / vi ที่ปรากฏในคือ 4.1cBSD ( @(#)ex_re.c 7.2 10/16/81และไม่มีใน 4BSD ( @(#)ex_re.c 6.2 10/23/80) [4.1a และ 4.1b ไม่มีอยู่ในไฟล์เก็บถาวร]

รหัสที่เกี่ยวข้องคือ:

/* ^V <return> from vi to split lines */
if (c == '\r')
    c = '\n';

สิ่งนี้ถูกกล่าวถึงในไฟล์ข่าว :

ตอนนี้เป็นไปได้ที่จะแบ่งบรรทัดด้วยคำสั่งทดแทนจาก vi โดยใช้ ^ V <return> ใน rhs สิ่งนี้จะคอยดูแลเหตุผลที่ดีสุดท้ายสำหรับการใช้โหมดคำสั่ง ex

พฤติกรรมที่ได้รับการสนับสนุนก่อนหน้านี้ในโหมดคำสั่ง ex ใช้สำหรับ backslash-enter (เช่น backslash ตามด้วย newline จริง) เพื่อแทรกขึ้นบรรทัดใหม่


0

ที่มาของความไม่สมดุลกลับไปเป็นวิธีการในประวัติศาสตร์คอมพิวเตอร์

เวอร์ชั่นสั้น:

<CR> & <LF>  (Carriage-Return and Linefeed) 
== 
\r & \n

รุ่นยาว:
หน้าจอแรกนั้นเป็นรุ่นของโทรศัพท์ระบบดิจิทัล (TTY) และใช้รหัสควบคุมเพื่อสร้างพฤติกรรมที่คล้ายคลึงกับเครื่องพิมพ์ Carriage-return เอาเคอร์เซอร์ (หรือหัวพิมพ์) ไปยังคอลัมน์เริ่มต้น Linefeed เข้าสู่แถวถัดไป (บนหน้าจอ) และป้อนกระดาษไปข้างหน้าหนึ่งบรรทัด

สำหรับเครื่องพิมพ์คุณต้องทำการจับคู่<CR><LF>หรือผลลัพธ์ของคุณจะไม่ถูกต้อง ในหน้าจอแรกปัญหายังคงเป็นจริง

DOS (และ sorta หน้าต่างหลัง) <CRLF>ตามมาตรฐานเดิมและบันทึกข้อความด้วย

* ข้อความ NIX (ผู้ใช้ที่คุ้นเคยกับ vi ส่วนใหญ่) ใช้<LF>เพื่อประสิทธิภาพเท่านั้น

หากต้องการทดสอบใน Windows ให้ใช้ Word / Wordpad และบันทึกข้อความสองสามบรรทัด "เป็นประเภท: ข้อความ - รูปแบบ MS-DOS" จากนั้นเปิดไฟล์เดียวกันนั้นใน Notepad มันควรจะดูปกติ จากนั้นให้บันทึกไฟล์เดียวกันใน Word / Wordpad "เป็นประเภท: Text" Notepad จะละเว้นบรรทัดใหม่ทั้งหมดและเรียกใช้บรรทัดด้วยกัน [รูปแบบข้อความของ Notepad จะใช้ค่าเริ่มต้นเป็น\r\nชุดค่าผสมในขณะที่ค่าเริ่มต้นของWord / Wordpad เป็น\n]

\ r เป็นโค้ดเทียบเท่า <CR>

\ n เป็นโค้ดเทียบเท่า <LF>

และจากประสบการณ์ของฉัน (จำกัด มาก) กับ vi มันจะพยายาม "แก้ไข" <CRLF>ชุดค่าผสมจากตัวแก้ไขข้อความ DOS ของฉัน vi <NUL>จบลงด้วยการเอาตัวละครตัวหนึ่งแทนที่ด้วย ส่วนใหญ่ของเหตุผลที่ฉันหยุดใช้ vi


2
ในขณะที่ข้อมูลทั้งหมดของคุณเป็นที่น่าสนใจก็เพียงบอกว่าทำไม\rเป็น<CR>และเป็น\n <LF>มันไม่ได้ตอบคำถามที่แท้จริงว่าทำไม\n\rพฤติกรรมต่างกันในบริบทที่แตกต่างกัน
Tumbler41

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