วิธีการกลับคำสั่งของเส้น?


24

ฉันจะกลับลำดับของบรรทัดเพื่อให้บรรทัดแรกปรากฏที่ท้ายและบรรทัดสุดท้ายปรากฏขึ้นได้อย่างไร (อาจเป็นทุกบรรทัดในบัฟเฟอร์ช่วงที่อยู่หรือการเลือกโหมดการแสดงผล linewise)

ฉันต้องการที่จะแปลง

rat
ox
tiger
⋮
dog
pig

เข้าไป

pig
dog
⋮
tiger
ox
rat

โดยไม่ต้อง resorting tacคำสั่งภายนอกเช่น


มีข้อเสนอแนะสำหรับแท็กที่ดีกว่าสำหรับคำถามนี้หรือไม่?
200_success

1
อาจเป็นแท็ก 'pure-vi' ใหม่หรือแท็กที่คล้ายกัน ฉันเคยเห็นคำถามหลายข้อที่จะได้รับประโยชน์จากแท็กที่จะระบุความต้องการที่จะไม่มีเครื่องมือภายนอกที่เกี่ยวข้อง ฉันควรถามเรื่องนั้นใน Meta หรือไม่
John O'M

1
@Carpetsmoker (และใครก็ตามที่สนใจติดตามนี้) คำถามเกี่ยวกับแท็กอยู่ใน meta meta.vi.stackexchange.com/questions/1229/…
John O'M

คำตอบ:


29

พลังของโลกจะทำงานที่นี่:

:g/^/exe "normal ddggP"

หรือมากกว่านั้นง่ายๆ (ขอบคุณ @tommcdo)

:g/^/move 0

ก่อนจะจับคู่ทุกบรรทัดและสำหรับแต่ละบรรทัดลบออกและวางไว้ที่ด้านบนของไฟล์ ในขณะที่มันเคลื่อนผ่านไฟล์มันจะกลับข้อความ

วินาทีที่คล้ายกันตรงกับทุกบรรทัดและย้ายไปที่ด้านบนของไฟล์

หมายเหตุ:ทั้งสองอย่างนี้ทำงานกับไฟล์ทั้งหมดและจะไม่สามารถใช้งานได้อย่างถูกต้องเพื่อย้อนกลับเซตย่อยของบรรทัด ดูคำตอบของ Ingo Karkatสำหรับวิธีการแก้ปัญหาที่ใช้งานได้ในช่วง

รายละเอียด:

gคำสั่งโกลบอล
/^/ตรงกับบรรทัดใด ๆ ที่มีจุดเริ่มต้น (เช่นทุกบรรทัด)
exeดำเนินการกับสตริงต่อไปนี้
"normalดำเนินการคำสั่งโหมดปกติ
ddลบบรรทัด
ggย้ายไปด้านบนของไฟล์
Pวางเหนือตำแหน่งปัจจุบัน

move 0 ย้ายบรรทัดปัจจุบันไปที่ด้านล่างบรรทัด 0 (ซึ่งวางไว้ที่ตำแหน่ง 1 หรือบรรทัดแรกของไฟล์)


6
แทนที่จะเป็น:normalคำสั่งเราสามารถใช้คำสั่ง Ex :move 0ซึ่งย้ายบรรทัดไปที่จุดเริ่มต้นของบัฟเฟอร์
tommcdo

1
นอกจากนี้ยังมีความจำเป็นเฉพาะเมื่อความต้องการของคำสั่งที่จะสร้างแบบไดนามิกเช่น:execute :execute 'normal' g:user_command
tommcdo

@tommcdo จุดดี! ฉัน:executeมักจะใช้เพราะฉันมักจะต่อท้ายคำสั่ง Ex อื่น ๆ หลังจากที่มีอยู่ในภายหลังและมันสะดวกสำหรับฉันที่จะมี:exeมันอยู่แล้วมากกว่าที่จะต้องกลับไปแทรกในภายหลัง น่าเสียดายที่นิสัยนั้นรั่วไหลออกมาในคำตอบนี้ซึ่งมันไม่ได้นำไปใช้มาก
John O'M

1
คำอธิบายเพิ่มเติมเกี่ยวกับการใช้งานของฉัน:execute: เนื่องจากต้องใช้สตริงจึงมีการแจกแจงที่ชัดเจนสำหรับคำสั่งโหมดปกติสิ้นสุดแม้ว่าฉันจะไม่ได้สร้างสตริง แต่ฉันก็สามารถหาเครื่องหมายคำพูดที่สมดุลได้ง่ายกว่าที่จะมองหา<esc>หรืออะไรก็ตามที่จะยุติโหมด อีกครั้งนี่คือความชอบส่วนตัวและนิสัย :-)
John O'M

3
สิ่งนี้จะใช้ได้กับช่วง btw: :9,11g/^/move 8... ตัวเลขสุดท้ายต้องเป็นจุดเริ่มต้นของช่วงลบ 1 (ดัดแปลงจากคำตอบของ Ingo)
Martin Tournoij

13

หนึ่งซับ (สำหรับคุณ~/.vimrc) นี้กำหนด:Reverseคำสั่ง คุณยังสามารถใช้ชิ้น:globalส่วนได้โดยตรง แต่ไวยากรณ์ของ:move(ซึ่งจะเลื่อนบรรทัดไปก่อนเริ่มช่วงดังนั้นจึงเป็นการย้อนกลับ) ไม่ใช่เรื่องง่ายที่จะจดจำ:

:command! -bar -range=% Reverse <line1>,<line2>global/^/m<line1>-1

1
ในฐานะที่เป็น FYI สำหรับผู้อ่านจำเป็นต้อง<line1>& <line2>เพื่อให้การทำงานนี้อยู่ในช่วงเช่น: :7,9Reverse(เป็นคุณลักษณะของcommandไม่ใช่globalหรือmove) ง่าย:command! -bar -range=% Reverse :global/^/m 0ยังจะทำงาน แต่สำหรับบัฟเฟอร์ทั้งหมด ...
มาร์ติน Tournoij

6

บริสุทธิ์เป็นกลุ่ม:

:g/^/m0

คำอธิบาย:

ตามที่:help multi-repeat, :gและญาติของ:vการทำงานในลักษณะที่สองรอบ

ครั้งแรกผ่านของ:gเครื่องหมายการจับคู่ทุกสาย{pattern}ในขณะที่ผ่านที่สอง (เห็นได้ชัดดำเนินการเริ่มต้นที่จุดเริ่มต้นของไฟล์และดำเนินการต่อไปที่สิ้นสุด) [cmd]ดำเนินการ การใช้งานด้านบนใช้:gประโยชน์จากการสั่งซื้อบรรทัดจะถูกประมวลผลใน (ซึ่งอาจจะไม่เป็นไร

มันทำงานโดยการทำเครื่องหมายทุกบรรทัดแรกจากนั้นย้ายบรรทัดที่ทำเครื่องหมายแรกไปที่ด้านบนของไฟล์จากนั้นย้ายที่สองไปที่ด้านบนของไฟล์ (เหนือบรรทัดที่ย้ายก่อนหน้านี้) จากนั้นบรรทัดที่ทำเครื่องหมายที่สาม บรรทัด) และอื่น ๆ จนกระทั่งบรรทัดสุดท้ายในไฟล์ถูกย้ายไปด้านบนทำให้การย้อนกลับไฟล์เป็นไปอย่างมีประสิทธิภาพ

โปรดทราบว่าหาก:gบรรทัดที่ประมวลผลในลำดับใด ๆ นอกเหนือจากบนลงล่างคำสั่งนี้จะไม่ทำงาน

ที่มา: ย้อนกลับทุกบรรทัดและพลังของ gที่ vim wikia

ตัวอย่างบางส่วนที่ใช้คำสั่งภายนอก:

  • tac(ส่วนหนึ่งของcoreutils GNU - catย้อนกลับ):

    :%!tac                                                                                                                                                                                                                                                              
    
  • tail บน BSD / OSX (ไม่สอดคล้องกับ POSIX):

    :%!tail -r
    

    -r อ็อพชัน -r ทำให้อินพุตถูกแสดงในลำดับย้อนกลับตามบรรทัด

    ตรวจสอบ: man tarสำหรับรายละเอียดเพิ่มเติม

สำหรับแนวคิดเพิ่มเติมดู:


2
ไม่:g/^/m0เหมือนกับ:g/^/move 0คำตอบของจอห์นใช่ไหม
muru

@muru ฉันคิดว่าเป็นเช่นนั้น แต่อันนี้สั้นกว่า (อ้างอิงจาก vim wikia) และฉันได้เพิ่มคำอธิบายที่แตกต่างพร้อมกับตัวอย่างเพิ่มเติมบางส่วนของการใช้บรรทัดคำสั่ง
kenorb

ใช่ฉันอัปโหลดเพราะคำสั่งอื่น (ฉันมาโพสต์tacด้วย) แต่ฉันสงสัยว่าการลงคะแนนเสียงนั้นเป็นเพราะคำตอบถูกทำซ้ำ
muru

ฉันรู้ว่าtacถูกกล่าวถึงโดย OP แต่คำถามที่คล้ายกันอื่น ๆ ทั้งหมดจะซ้ำกับคำถามนี้ดังนั้นจึงเป็นการดีที่จะกล่าวถึงอีกครั้ง John เอา cmd นี้จาก @tommcdo คอมเม้นท์ฉันเอามันมาจากDerMikeแต่ฉันคิดว่าเขาเอามันมาจาก wikia ดังนั้นฉันจึงให้เครดิตกับ vim wikia ดังนั้นจึงไม่ซ้ำกันอย่างสมบูรณ์เนื่องจากคำอธิบายนั้นแตกต่างอย่างสิ้นเชิง
kenorb

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

6

ในจิตวิญญาณของ VimL ที่ใช้งานได้:

:call setline(1, reverse(getline(1, line('$'))))
  • getline(1, line('$'))ส่งคืนรายการของบรรทัดทั้งหมดในบัฟเฟอร์ '$'เป็นอาร์กิวเมนต์พิเศษline()ที่ระบุบรรทัดสุดท้ายในบัฟเฟอร์
  • reverse(...)ย้อนกลับรายการอินพุตในสถานที่ หนึ่งจะต้องใช้reverse(copy(...))หากไม่ควรแก้ไขรายการอินพุต
  • setline(1, ...)แทนที่บรรทัดที่ระบุด้วยอาร์กิวเมนต์ที่สอง เมื่ออาร์กิวเมนต์ที่สองเป็นรายการจำนวนบรรทัดเดียวกันกับความยาวของรายการจะถูกแทนที่ด้วยเนื้อหาของรายการ

หากคุณต้องการคุณยังสามารถกำหนดคำสั่งที่ใช้ช่วง ( %บัฟเฟอร์เริ่มต้นทั้งหมด)

:command! -bar -range=% Reverse call setline(<line1>, reverse(getline(<line1>, <line2>)))

1
ฉันชอบคำตอบนี้ นอกจากนี้ยังไม่เน้นสิ่งต่าง ๆ (ถ้าhlsearchเปิดใช้งาน) เช่น:g/คำสั่งจากคำตอบอื่น ๆ ... ประสิทธิภาพอาจแย่ลงได้ไหม? เนื่องจากมันgetline(1, line('$'))ได้รับบัฟเฟอร์ทั้งหมดในหน่วยความจำ reverse()น่าจะเป็นในสถานที่เพื่อที่จะใช้หน่วยความจำน้อยมากเช่น ...
มาร์ติน Tournoij

3

ตามเอกสาร Vim usr_12.txt - เคล็ดลับที่ชาญฉลาด

12.4 การสั่งซื้อย้อนกลับบรรทัด

:globalคำสั่งสามารถใช้ร่วมกับ:moveคำสั่งที่จะย้ายทุกบรรทัดก่อนบรรทัดแรกส่งผลให้ในไฟล์ตรงกันข้าม คำสั่งคือ:

:global/^/m 0

ย่อ:

:g/^/m 0

^แสดงออกปกติตรงกับจุดเริ่มต้นของบรรทัด (แม้ว่าสายไม่ว่าง) :moveคำสั่งย้ายการจับคู่สายเพื่อหลังจากที่สายข้อที่ศูนย์ตำนานดังนั้นการจับคู่สายในปัจจุบันกลายเป็นบรรทัดแรกของไฟล์ เนื่องจาก:globalคำสั่งไม่สับสนโดยการเปลี่ยนหมายเลขบรรทัด:globalดำเนินการเพื่อจับคู่บรรทัดที่เหลือทั้งหมดของไฟล์และทำให้แต่ละรายการเป็นบรรทัดแรก

สิ่งนี้ยังทำงานในช่วงของเส้น mtย้ายครั้งแรกถึงข้างต้นบรรทัดแรกและทำเครื่องหมายด้วย จากนั้นเลื่อนเคอร์เซอร์ไปที่บรรทัดสุดท้ายในช่วงและประเภท:

:'t+1,.g/^/m 't

1

ใช้ตัวเลขที่สัมพันธ์กัน ย่อหน้าเริ่มต้นที่บรรทัดที่ 13 และ spams มากกว่า 4 บรรทัด

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