เป็นกลุ่ม - วิธีการแทนที่หนึ่งบรรทัดใหม่ \ n ด้วยสอง \ n's


34

ในโปรแกรมแก้ไข vim ฉันต้องการแทนที่อักขระขึ้นบรรทัดใหม่ (\ n) ด้วยอักขระบรรทัดใหม่สองตัว (\ n \ n) โดยใช้โหมดคำสั่ง vim

เนื้อหาไฟล์อินพุต:

This is my first line.
This is second line.

คำสั่งที่ฉันพยายาม:

:%s/\n/\n\n/g

มันจะแทนที่สตริงด้วยอักขระที่ไม่ต้องการเช่น

This is my first line.^@^@This is second line.^@^@

จากนั้นฉันลองคำสั่งต่อไปนี้

:%s/\n/\r\r/g

มันทำงานอย่างถูกต้อง คุณช่วยอธิบายได้ไหมว่าทำไมมันถึงใช้ได้ดีกับคำสั่งที่สอง?


ดูเพิ่มเติมที่unix.stackexchange.com/a/206404
Stéphane Chazelas

2
FYI: นอกจากนี้ยังมีVi และเป็นกลุ่ม (เบต้า) SE
Dubu

2
หมายเหตุด้านข้างคุณไม่จำเป็นต้องใช้/เป็นตัวคั่น นี่สามารถอ่านได้มากขึ้น::%s;\n;\n\n;g
DJMcMayhem

1
ค้นหา\n, แทนที่ด้วย\r\r, :% s/\n/\r\r/g: stackoverflow.com/a/71334/911945
Anton Tarasenko

คำตอบ:


47

ผิดปกติพอ\nในกลุ่มสำหรับการทดแทนไม่ได้หมายถึงการขึ้นบรรทัดใหม่ แต่เป็นโมฆะ ASCII nul คือ^@( control@)

ในอดีต vi จะแทนที่^M( controlM) เป็นบรรทัดสุดท้ายซึ่งเป็นบรรทัดใหม่ เป็นกลุ่มเพิ่มส่วนขยาย\r(เช่นภาษา C) เพื่อหมายถึงเหมือนกัน^Mแต่นักพัฒนาเลือกที่จะทำให้\nค่าเฉลี่ยเป็นโมฆะเมื่อแทนที่ข้อความ สิ่งนี้ไม่สอดคล้องกับการใช้งานในการค้นหาซึ่งค้นหาการขึ้นบรรทัดใหม่

อ่านเพิ่มเติม:


7

ลองนี้: %s/$/^V^M/(ในกรณีที่^Vเป็นCtrl-Vและ^Mเป็นCtrl-M- เมื่อคุณพิมพ์^Vจะพิมพ์^ถ่านแล้ว Backspace มากกว่านั้นและจากนั้นเมื่อคุณพิมพ์^Mจะปรากฏเป็น^M... ปุ่ม Ctrl-V เป็น TTY มาตรฐานที่แท้จริงต่อไปของตัวละคร - เรียกใช้คำสั่งstty -aการ แสดงตัวอักษรพิเศษของ tty ของคุณ)


แน่นอนว่าผู้ที่มีประสบการณ์มากจะรู้สิ่งนี้สำหรับการแปลงที่จำเป็นจาก CRLF เพื่อเป็นทางเลือกในการเลื่อนออกและใช้ dos2unix หรือสิ่งที่คล้ายกัน การใช้งาน Ctrl-V เป็นบทเรียนวันที่ 1 vi
mckenzm

5

vimใช้\nเพื่อแทนอักขระ null \0ในหน่วยความจำว่าวิธีvimจัดการกับไฟล์มีอักขระ null (ในขณะที่viไม่สามารถ)

การใช้การ\nจับคู่เฉพาะจุดสิ้นสุดบรรทัดในบัฟเฟอร์ไม่ใช่การขึ้นบรรทัดใหม่ในสตริงเมื่อใช้ในนิพจน์

ดู: h NL-used-for-Nullและ: h CR-used-for-NLสำหรับรายละเอียดเพิ่มเติม


1

ทดสอบกับ Neovim ( nvim) และVimรุ่นต่างๆ

NVIM v0.3.0
VIM - Vi IMproved 8.1

ลบบรรทัดใหม่:

cell
allele
rs2981578
fgfr2

นี่\nตรงกับการขึ้นบรรทัดใหม่ (เพื่อแทรกบรรทัดใหม่ แต่การใช้งาน\r):

:'<,'>s/\n/|/g

cell|allele|rs2981578|fgfr2

เพิ่มบรรทัดใหม่:

Nope:

cell|allele|rs2981578|fgfr2

:'<,'>s/\n/|/g

cell^@allele^@rs2981578^@fgfr2

^@เป็นเครื่องหมายกำกับเสียงสำหรับ LF (ตัวดึงข้อมูลบรรทัดดู http://vimhelp.appspot.com/digraph.txt.html#digraphs-default )

ใช่:

cell|allele|rs2981578|fgfr2

:'<,'>s/|/\r/g

cell
allele
rs2981578
fgfr2

หากต้องการตอบคำถามของ OP (วิธีแทนที่หนึ่ง\nด้วยสอง\n\n) ให้เพิ่มอีก\r:

cell
allele
rs2981578
fgfr2

:'<,'>s/\n/\r\r/g

cell

allele

rs2981578

fgfr2

... ie จับคู่ newline ดั้งเดิม ( \n) และแทนที่ด้วย newline / carriage return ( \r\r)

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