การแทนที่หลายบรรทัดว่างด้วยบรรทัดว่างเดี่ยวใน vim / sed


42

คำถามไม่มากก็น้อยบอกว่ามันทั้งหมด ฉันทราบว่า/^$/dจะลบบรรทัดว่างทั้งหมด แต่ฉันไม่เห็นวิธีพูดว่า 'แทนที่บรรทัดว่างสองบรรทัดขึ้นไปด้วยบรรทัดว่างเดียว'

ความคิดใด ๆ

คำตอบ:


48

ถ้าคุณไม่ได้ยิงเป็นกลุ่มหรือ sed สำหรับบางใช้งานอื่น ๆ cat -sแมวจริงมีวิธีที่ง่ายในตัวที่จะยุบบรรทัดว่างหลายเพียงแค่การใช้งาน

หากคุณอยู่ในกลุ่มแล้วและต้องการที่จะอยู่ที่นั่นคุณสามารถทำได้ด้วยการค้นหาภายในและแทนที่ด้วยการออก: :%s!\n\n\n\+!^M^M!g(^ M คือการแสดงภาพของบรรทัดใหม่คุณสามารถป้อนมันโดยกดปุ่มCtrl+ vEnter) หรือช่วยตัวเอง พิมพ์โดยใช้ปลอกกระสุนแมว: :%!cat -s.


ว้าวไม่ทราบว่า-sตัวเลือกของแมว - แค่บันทึกประวัติศาสตร์มันไม่ได้อยู่ใน POSIX แต่ดูเหมือนว่าจะมีอยู่ในแมว BSD และ GNU
maxschlepzig

2
ทำเครื่องหมายว่า 'ชนะ' :%!cat -sสำหรับ เรียนรู้สิ่ง GNnew ทุกวัน!
Andrew Bolster

3
ฉันคิดว่าคุณสามารถใช้ \ r แทน ^ M เช่นนี้:%s!\n\n\n\+!\r\r!g
Niko Bellic

ฉันต้องการสิ่งนี้ในวันนี้ ขอบคุณ Caleb! :)
Dɑvïd

19

ใช้\nเพื่อระบุบรรทัดใหม่ในรูปแบบการค้นหา ใช้Ctrl+ Mในข้อความแทนหรือ backreference ดู:help patternและ:help sub-replace-special(เชื่อมโยงจาก:help :s)

%s/\(\n\n\)\n\+/\1/

คุณช่วยอธิบายรูปแบบการค้นหาได้อย่างไร
Sagar Jain

@sjmp Requirement: แทนที่บรรทัดว่างสองบรรทัดขึ้นไปด้วยบรรทัดว่างหนึ่งบรรทัด การใช้งาน: แทนที่บรรทัดใหม่อย่างน้อยสามบรรทัดขึ้นไปด้วยบรรทัดใหม่เพียงสองบรรทัด ดูคู่มือสำหรับคำอธิบายของการสร้างที่ใช้ในคำสั่ง
Gilles 'หยุดความชั่วร้าย'

แต่ทำไมคุณต้องใช้กลุ่มเมื่อเนื้อหาได้รับการแก้ไข
Sabuncu

@Sabuncu คุณไม่จำเป็นต้องใช้กลุ่ม แต่ทำไมไม่ใช้กลุ่ม ที่นี่ฉันใช้กลุ่มเพราะคุณไม่สามารถคัดลอกวางคำสั่งที่มีบรรทัดใหม่ในข้อความแทนที่: คุณต้องแทรกตัวอักษร Ctrl + M ตัวอักษร\nไม่ทำงานในข้อความแทนที่
Gilles 'หยุดความชั่วร้าย'

ตอนนี้ฉันเข้าใจแล้วขอบคุณที่สละเวลาตอบ
Sabuncu

6

หากอยู่ในกลุ่มให้ทำดังนี้

:%!cat -s

2
คุณอาจต้องการเพิ่มรายละเอียดเล็ก ๆ น้อย ๆ เกี่ยวกับวิธีการทำงานแม้ว่ามันจะเป็นเพียงคำพูดจากmanหน้า
jasonwryan

ไม่ทำงานบน windows 7
user674669

0

ใช้ Perl:

perl -00 -pe ''

-00 ตัวเลือกบรรทัดคำสั่งเปิดโหมด slurp ย่อหน้าหมายถึง Perl อ่านย่อหน้าข้อความตามย่อหน้าแทนที่จะเป็นบรรทัดต่อบรรทัด


0

ด้วย sed (GNU sed) 4.2.2:

sed -r '
  /^\s*$/ { 
    # blank line
:NEXT
    N # append next line to pattern space - if none, autoprint PS and exit
    s/^\s*$\n^\s*$//g;t NEXT # if 2 blank lines, clear PS and loop to NEXT
  }
  # else, autoprint PS and next/exit
' < $MYFILE

-2

ฉันรู้ว่านี่เป็นรหัสโง่ แต่ฉันต้องการแก้ปัญหานี้ในเวลาน้อยกว่า 10 นาทีและใช้งานได้

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done

1
uniqลบบรรทัดเท่ากับที่อยู่ติดกัน ซึ่งไม่ใช่สิ่งที่ OP ต้องการ
pacholik

@pacholik เขาพูดอย่างชัดเจนว่า "การแทนที่หลายบรรทัดว่างด้วยบรรทัดว่างเดียว" อย่าลบบรรทัดที่อยู่ติดกัน !!!
Mahmoud Zalt

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