ทำไมกลุ่มถึงเพิ่มขึ้นบรรทัดใหม่? นี่คือการประชุมหรือไม่?


22

หากฉันเปิดเป็นกลุ่มและพิมพ์itest<Esc>:wqฉันจะได้รับไฟล์ที่ไม่มีบรรทัดใหม่ใน Vimแต่ดูเหมือนจะมีบรรทัดใหม่ในรหัส:

$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a                    |test.|
00000005

หากฉันเปิดเป็นกลุ่มและพิมพ์itest<Return><Esc>:wqฉันจะได้รับไฟล์ที่มีหนึ่งบรรทัดใน Vimแต่ขึ้นบรรทัดใหม่สองบรรทัดในรหัส:

$ rm test.txt
$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a 0a                 |test..|
00000006

โปรดทราบว่าฉันกำลังเปิด Vim ด้วย-u NONEดังนั้นจึงไม่มีการกำหนดค่าในเครื่อง ยังทราบว่าเรื่องนี้อาจจะเกี่ยวข้องกับคำถามก่อนหน้านี้ของฉัน

นี่คือข้อมูลระบบของฉัน:

$ uname -a
Linux awsAlpha 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:25:35)
Included patches: 1-429
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

ฉันสามารถยืนยันพฤติกรรมที่เหมือนกันที่แน่นอนในระบบนี้เช่นกัน:

$ uname -a
Linux bruno 3.5.0-48-generic #72-Ubuntu SMP Mon Mar 10 23:18:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 26 2012 16:45:33)
Included patches: 1-547
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

ทำไมกลุ่มถึงเพิ่มขึ้นบรรทัดใหม่? นี่คือการประชุมหรือไม่?

นี่คือคำอธิบายบางอย่างเกี่ยวกับhdคำสั่งที่ติดตั้งบนเซิร์ฟเวอร์ Ubuntu:

$ man hd | head -4
HEXDUMP(1)            BSD General Commands Manual            HEXDUMP(1)

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump

8
ดูเหมือนว่าจะเป็นการประชุม นี่คือวิธีการปิดการใช้งานถ้าคุณต้องการ นี่คือประวัติของสิ่งนี้
jliv902

คำตอบ:


28

ข้อตกลงสำหรับไฟล์ข้อความ Unix คือทุกบรรทัดถูกยกเลิกโดยการขึ้นบรรทัดใหม่และการขึ้นบรรทัดใหม่นั้นเป็นตัวยกเลิกบรรทัดไม่ใช่ตัวคั่นบรรทัด

เมื่อ Vim บันทึกบัฟเฟอร์เป็นไฟล์มันจะยกเลิกทุกบรรทัดที่มีลำดับการสิ้นสุดของบรรทัดสำหรับรูปแบบไฟล์นั้นซึ่งสำหรับ Unix นั้นเป็นบรรทัดใหม่ ดู

:help 'fileformat'

หากคุณใช้เครื่องมือประมวลผลข้อความ Unix วิธีที่ดีที่สุดคือปฏิบัติตามอนุสัญญานี้ อย่างไรก็ตามหากคุณมีความต้องการที่จะไม่ต้องวางบรรทัดใหม่ที่ท้ายบรรทัดสุดท้ายของไฟล์คุณสามารถทำได้ Vim ถือว่าไฟล์ดังกล่าวเป็น "binary" ดู

:help 'binary'
:help edit-binary

1
โอ้มันน่าสนใจ ดังนั้นนอกจากชื่อเสียง \ r \ n กับ \ n Windows ใช้ตัวแยกบรรทัดและยูนิกซ์ใช้ตัวคั่นบรรทัดหรือไม่? และมีการบันทึกไว้ที่ไหนบ้าง? ฉันรู้ว่ามันถูกกำหนดที่นี่น่าจะนำไปใช้กับยูนิกซ์ "ISO / IEC 9899: 2011, มาตรา .27.21.2 Streams พูดว่า: กระแสข้อความเป็นลำดับลำดับของตัวละครประกอบด้วยบรรทัดแต่ละบรรทัดประกอบด้วยศูนย์หรือมากกว่าตัวอักษรใหม่ อักขระบรรทัด "
barlop

แต่มันอยู่ที่ไหนเอกสาร windows ใช้ตัวคั่นบรรทัด
barlop

2

เสียงเรียกเข้าไม่ได้เพิ่มอะไรที่คุณไม่ได้ทำเอง

อักขระ "ขึ้นบรรทัดใหม่" ไม่ใช่ "บรรทัดใหม่" และทั้งสองตัวอย่างนั้นเป็นปกติอย่างสมบูรณ์:

  • ในอันแรกไฟล์มีเพียงหนึ่งบรรทัดเพื่อให้คุณได้รับหนึ่งตัวอักษร "ขึ้นบรรทัดใหม่"
  • ในส่วนที่สองไฟล์มีสองบรรทัดเพื่อให้คุณได้รับอักขระ "newline" สองตัว

2
มันจะเพิ่มขึ้นบรรทัดใหม่ ทดสอบดังนี้printf "\x41" > /tmp/test.txtแล้วตรวจสอบว่ามีเพียงคนเดียว 'A' xxd /tmp/test.txtตัวละครด้วย vim /tmp/test.txt<ENTER>:wqตอนนี้ ตรวจสอบอีกครั้งเพื่อดูไฟล์ที่มีสองไบต์: 'A \ n'
Ruslan

บรรทัดลงท้ายด้วยอักขระขึ้นบรรทัดใหม่ คุณมีหนึ่งบรรทัดจึงมีอักขระขึ้นบรรทัดใหม่หนึ่งบรรทัด
romainl

หลังจากprintfที่นี่ฉันไม่มี "เส้น" รูปแบบที่ดี หลังจากเป็นกลุ่มฉันมี ดังนั้นมันจะเพิ่มสิ่งที่ฉันไม่ได้ใส่
Ruslan

สิ่งที่คุณไม่ได้เป็นเส้นเว้นแต่คุณผนวกprintf \nการเป็นตัวแก้ไขข้อความ Vim จัดการกับบรรทัดตามค่าเริ่มต้นและข้อความใด ๆ ที่คุณแทรกในไฟล์นั้นเปิดอยู่อย่างน้อยที่สุดหนึ่งบรรทัดยกเว้นว่าคุณจะบอกให้ Vim อย่างชัดเจนไม่ควรทำเช่นนั้น
romainl

2

ไฟล์ข้อความที่ไม่ได้ถูกทำลายนั้นมีความชั่วหลายประการ นี่คือสิ่งที่ฉันยังไม่เห็นพูดถึง:

ในโลกสมมุติที่ไฟล์ข้อความที่ไม่มีบรรทัดใหม่ต่อท้ายเป็นที่ยอมรับจะไม่มีความแตกต่างระหว่างไฟล์ที่มี 0 บรรทัดและไฟล์ที่มี 1 บรรทัดว่าง พวกเขาทั้งสองจะถูกแสดงด้วยไฟล์ 0 ไบต์

การไม่สามารถตัดสินใจได้ว่าจำนวนบรรทัดในไฟล์จะไม่ดี


ไฟล์ข้อความในระบบที่ไม่ใช่ Unix มีบรรทัดที่สมบูรณ์เป็นศูนย์หรือมากกว่ารวมถึงบรรทัดที่ไม่สมบูรณ์ซึ่งมีอักขระเป็นศูนย์หรือมากกว่า ไฟล์ว่างไม่มีบรรทัดว่าง มันมีศูนย์เส้นสมบูรณ์และเส้นบางส่วนของศูนย์ตัวอักษร ความกำกวมอยู่ที่ไหน
supercat

"เส้นบางส่วน" นี้เป็นแนวคิดที่ไม่พึงประสงค์ คุณไม่สามารถมีหนึ่งที่อื่นนอกเหนือจากจุดสิ้นสุดของไฟล์และคุณไม่สามารถสร้างไฟล์ที่ไม่มี "บางส่วนของบรรทัด" มันเพิ่มความแตกแยกมากขึ้นในการจัดเรียงไฟล์ - แม้ว่าคุณจะแทรกบรรทัดใหม่ระหว่างไฟล์ที่คุณลงท้ายด้วยบางสิ่งที่ไม่เทียบเท่ากับคู่ดั้งเดิมของไฟล์ (เพราะมี 2 ไฟล์คุณมี 2 บางส่วนของบรรทัดและหนึ่งในนั้นกลายเป็นอะไรบางอย่าง ที่แตกต่างกัน) ข้อเสนอที่ไม่เกี่ยวข้อง

ความจริงที่ว่าการต่อไฟล์จะทำให้บางส่วนของบรรทัดในตอนท้ายของไฟล์แรกที่ต่อท้ายกับไฟล์ถัดไปเป็นเรื่องปกติในกรณีที่ทั้งสองไฟล์มีบรรทัดเต็ม (บางครั้งอาจมีประโยชน์ในการต่อไฟล์ที่ไม่มีบรรทัดเต็ม ) แต่มันคือสิ่งที่มันเป็น Unix ไม่ห้ามการสร้างไฟล์ข้อความที่ลงท้ายด้วยบางส่วนและฉันเชื่อว่าการต่อไฟล์ดังกล่าวจะทำงานเหมือนใน MSDOS ความแตกต่างที่ผมคิดว่าเป็นสิ่งที่หลายบรรณาธิการ DOS ตามมีการดำเนินการในอดีตมุมมองที่โหลดและทันทีที่บันทึกไฟล์ควรผลผลิตไฟล์ใหม่ ...
SuperCat

... ซึ่งเหมือนกันกับบิตเก่า (ผู้ใช้ที่ลงทะเบียนในเวอร์ชั่นแรกของพีซี - เขียนได้รับคำสั่งให้ใช้เพื่อเปิดสำเนาของไฟล์ปฏิบัติการสลับไปที่โหมดเขียนทับค้นหาสตริงที่แน่นอนและแทนที่ด้วย หมายเลขซีเรียล!) การบังคับให้ไฟล์จบด้วยการขึ้นบรรทัดใหม่เมื่อบันทึกไฟล์จะเป็นการละเมิดข้อ จำกัด ดังกล่าว
supercat

2

เป็นกลุ่ม 8.0 ตอนนี้ให้สำหรับfixeolตัวเลือกนี้ โดยเฉพาะถ้าคุณ:

:set nofixeol

Vim จะไม่เพิ่มอักขระขึ้นบรรทัดใหม่ที่ท้ายบรรทัดสุดท้ายหากไฟล์ยังไม่มี

ที่อาจจะไปในปลั๊กอิน filetype .vimrcหรืออาจเป็นไปได้ของคุณ

(นี่คือการปรับปรุง:set binaryเนื่องจากจะมีผลกับอักขระตัวแบ่งบรรทัดสุดท้ายเท่านั้นในขณะที่binaryยังเปลี่ยนพฤติกรรมอื่น ๆ อีกมากมายซึ่งคุณอาจไม่ต้องการเว้นแต่ว่าคุณกำลังแก้ไขไฟล์ไบนารี่จริง ๆ )

ไฟล์ที่สร้างขึ้นใหม่จะยังคงมีตัวละครแบ่งบรรทัดตามค่าเริ่มต้น คุณสามารถเปลี่ยน (และเปลี่ยนไฟล์ที่มีการขึ้นบรรทัดใหม่สุดท้ายเป็นไม่มีไฟล์) ได้โดยทำดังนี้:

:set noeol

ที่จะต้องมีการตั้งค่าโดยเฉพาะสำหรับแต่ละไฟล์ที่คุณต้องการเปลี่ยนแปลง: การโหลดไฟล์ลงในบัฟเฟอร์มักจะตั้งค่าeolให้ตรงกับสถานะปัจจุบันของไฟล์


1

การใช้คำสั่ง 'j' คุณสามารถเข้าร่วมทุกบรรทัดเป็นหนึ่งเดียว

หากคุณต้องการลบ LF หรือ CRLF ในบรรทัดสุดท้ายให้ทำดังต่อไปนี้ใน vi

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.