วิธีเขียนบัฟเฟอร์ทั้งหมดไปยังเอาต์พุตมาตรฐานจากบรรทัดคำสั่ง?


10

ฉันต้องการเขียนบัฟเฟอร์ทั้งหมดลงในเอาต์พุตมาตรฐาน ( /dev/stdout) แทนไฟล์และคำสั่งต่อไปนี้ทำงานตามที่คาดไว้ในขณะที่แก้ไขไฟล์:

:w >> /dev/stdout

คำแนะนำ: กดControl+ Lเพื่อรีเฟรชหน้าจอ

แต่มันไม่ทำงานอย่างที่คาดไว้เมื่อฉันพยายามทำสิ่งเดียวกันจากบรรทัดคำสั่ง (แบบไม่โต้ตอบ ):

$ echo This is example. | vim - '+:w >> /dev/stdout' '+:q!'
Vim: Reading from stdin...

เช่นเดียวกันกับ:w !tee, :x! /dev/stdout, :%printและที่คล้ายกัน

ก่อนที่จะเลิกพูดว่า: [Device] 1L, 17C appended.

มีวิธีการบังคับให้ vim เขียนอินพุตมาตรฐานลงในเอาต์พุตมาตรฐานตรงกลางของไพพ์หรือไม่? อาจจะถูกบัฟเฟอร์อย่างใด?


4
แค่อยากรู้อยากเห็นคุณพยายามทำอะไร เช่นเดียวกับในกลุ่มคุณจะทำอะไรให้คุณที่นี่ที่เครื่องมืออื่นอาจไม่
Jay Thompson

1
@ JayThompson ฉันพยายามที่จะใช้vimสำหรับการแยกวิเคราะห์ไฟล์แทนsed(เช่นการเปลี่ยนแปลงที่ซับซ้อนซ้ำซ้อนกับไฟล์ขนาดใหญ่หลาย ๆ ไฟล์) ตัวอย่างที่ไม่ได้ทำอะไรให้มันง่ายและไม่ได้ทำซ้ำที่มีศักยภาพของผู้อื่นโพสต์
kenorb

คุณรู้เกี่ยวกับ vipe แล้วเหตุผลใดที่คุณไม่ได้ใช้มัน?
muru

@muru ฉันยังไม่ได้ใช้ แต่ยังมีเอกสารไม่มากและไม่ได้อยู่ที่นี่
kenorb

อาจมีคำถามเกี่ยวกับ vipe แต่ไม่มีเหตุผลที่มันจะไม่เป็นคำตอบ ดังนั้นฉันสงสัยว่าทำไมฉันไม่ควรโพสต์มันเป็นคำตอบ
muru

คำตอบ:


9

หากต้องการพิมพ์บัฟเฟอร์ไปยังเอาต์พุตมาตรฐานเชลล์vimจำเป็นต้องเริ่มต้นในโหมด Ex มิฉะนั้นจะเปิดวิธี "ปกติ" ด้วยหน้าต่างของตัวเองและล้างบัฟเฟอร์เอาต์พุตใด ๆ เมื่อออก

นี่คือตัวอย่างการทำงานที่ง่ายที่สุด:

$ echo foo | vim -e '+%print' '+q!' /dev/stdin
foo

หรือสั้นกว่า:

$ echo foo | ex +%p -cq! /dev/stdin
$ echo foo | ex +"%p|q!" /dev/stdin

หมายเหตุ: vim -eโดยทั่วไปคำสั่งนั้นเทียบเท่ากับexคำสั่ง

ต้องระบุไฟล์พิเศษไปยังอินพุตมาตรฐาน ( /dev/stdin) เพื่อป้องกันข้อความพิเศษที่น่ารำคาญ (ดังอธิบายด้านล่าง)


และนี่คือตัวอย่างบางส่วนที่มีการแยกวิเคราะห์สตริง:

$ echo This is example. | vim -e '+s/example/test/g' '+%print' '+q!' /dev/stdin
This is test.
$ echo This is example. | vim - -es '+s/example/test/g' '+%print' '+q!'
Vim: Reading from stdin...
This is test.

หมายเหตุ: ตัวอย่างสุดท้ายแสดงข้อความที่น่ารำคาญเป็นพิเศษซึ่งไม่สามารถซ่อนได้นั่นเป็นเพราะกลยุทธ์มาตรฐานในการอ่านไฟล์ทั้งหมดลงในหน่วยความจำและบอกว่าอ่านจากอินพุตมาตรฐาน ตัวอย่างแรกทำงานได้โดยไม่มีข้อความเนื่องจากไฟล์สร้างข้อมูลที่ไม่มีที่สิ้นสุดโดยไม่มีสัญญาณสิ้นสุดไฟล์ ( EOF ) ดังนั้นมันจะไม่สิ้นสุดการอ่านอินพุต


ที่เกี่ยวข้อง:


1
คุณสามารถทำได้+q!มากกว่า+:q!ใช่มั้ย
Andrew

@AndrewMacFie เป็นสิ่งเดียวกันอัพเดทขอบคุณ
kenorb

3

vipeเป็นเครื่องมือที่สะดวกสำหรับการแก้ไขท่อซึ่งเป็นส่วนหนึ่งของmoreutilsแพ็คเกจ มันเป็นเสื้อคลุมสำหรับบรรณาธิการ (รวมถึงสิ่งviที่ทำให้มันชื่อ) มันใช้EDITORตัวแปรสภาพแวดล้อมในการตั้งค่าการแก้ไขดังนั้นเช่นเดียวกับเครื่องมืออื่น ๆ ที่ทำให้การใช้งานEDITOR(เช่นcrontab, visudoฯลฯ ), คุณกระทำสคริปต์สามารถใช้ตัวแปรที่ ตัวอย่างเช่นคุณสามารถเปลี่ยนเป็น:

$ echo foo | EDITOR='vim +:s/foo/bar/ +wq' vipe | tail
bar

แน่นอนการกระทำที่ซับซ้อนอาจตกไปสู่การอ้างถึงนรกดังนั้นคุณสามารถเขียนสคริปต์:

#! /bin/sh

vim "+:s/foo/bar" '+wq' "$@"

EDITOR="sh /path/to/script"และการใช้งาน

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