วิธีแก้ไขไฟล์แบบไม่โต้ตอบ (เช่นในไพพ์ไลน์)?


24

ฉันต้องการแก้ไขไฟล์ที่ส่งผ่านไปป์ไลน์โดยใช้ vim แบบไม่โต้ตอบหรือแก้ไขไฟล์ในตำแหน่ง (คล้ายกับsed)

ตัวอย่างการใช้sed:

$ sed -i'.bak' s/foo/test/g file   # Edit file in-place.
$ cat file | sed s/foo/test/g      # Parse file in pipeline.

อย่างไรก็ตามฉันสามารถอ่านที่นี่ว่า:

sedเป็นS tream ED itor ไม่ใช่ตัวแก้ไขไฟล์ อย่างไรก็ตามผู้คนทุกที่มีแนวโน้มที่จะละเมิดมันสำหรับพยายามแก้ไขไฟล์ มันไม่ได้แก้ไขไฟล์

ประการที่สองตัวเลือกบางอย่างเช่นการแก้ไขในสถานที่ ( -i) เป็นแบบพกพา

วิธีการทำงานเหมือนกันสามารถทำได้ในกลุ่ม?


ฉันคิดว่าคุณสามารถดรอปวินาทีfileจาก commandline ที่สองของคุณ
joeytwiddle

@joeytwiddle เรียบร้อยแล้ว
kenorb

คำตอบ:


33

หากต้องการแก้ไขไฟล์โดยไม่ใช้การโต้ตอบex( viเป็นโหมดภาพex) คุณสามารถใช้+{command}หรือ-c {command}พารามิเตอร์ที่อนุญาตให้คุณรันคำสั่ง vi หลังจากอ่านไฟล์แรก

exเป็นบรรณาธิการบรรทัดคำสั่งมาตรฐาน (คล้ายกับed)

นอกจากนี้ยังมีvipe(ควรใช้โปรแกรมแก้ไขคำสั่ง Vim) ซึ่งเป็นส่วนหนึ่งของmoreutilsแพ็คเกจและมันจะช่วยให้คุณสามารถเรียกใช้โปรแกรมแก้ไขของคุณตรงกลางของไปป์ไลน์ unix และแก้ไขข้อมูลที่ถูกไพพ์ระหว่างโปรแกรม

ตัวอย่าง

เชลล์อินพุตและเอาต์พุตมาตรฐานโดยใช้ไพพ์สามารถทำได้ด้วยไวยากรณ์เชลล์นี้:

$ ex -sc'%p|q!' <(echo Example)
$ echo Example | ex -sc'%p|q!' /dev/stdin

นี่คือตัวอย่างง่ายๆวิธีการพิมพ์ไฟล์หลังการทดแทน:

$ ex /etc/hosts +%s/127/128/ge -sc'%p|q!'

ตัวอย่างเพิ่มเติมสำหรับการแก้ไขไฟล์แบบแทนที่:

$ ex +'%s/127/128/g' -cswq file
$ ex -sc '%s/olddomain\.com/newdomain.com/g|x' file
$ printf '%s\n' 'g/olddomain\.com/s//newdomain.com/g' w q | ex -s file
$ ex -s "$file" <<< $'g/old/s//new/g\nw\nq'
$ ex -sc 'argdo %s/old/new/ge|x' ./**
$ find . -type f -exec ex -sc '%s/old/new/g|x' {} \;

คุณยังสามารถใช้-s {scriptin}เพื่อให้คำสั่งถูกโหลดจากไฟล์ตัวอย่าง:

$ printf "%s\n" '%s/foo/test/ge' 'wq' > cmds.vim
$ vim -s cmds.vim -es file

หรือใช้การเปลี่ยนเส้นทาง I / O:

$ vim file < cmds.vim

หากต้องการแก้ไขไฟล์เดียวและบันทึกการเปลี่ยนแปลงเป็นไฟล์อื่นให้ตรวจสอบตัวอย่างต่อไปนี้:

$ ex +%s/127/128/g -sc'wq! new_file' /etc/hosts
$ cat /etc/hosts /etc/fstab | vim - -es '+:%s/foo/test/g' '+:wq! file3'

ตัวอย่างการปฏิบัติเพิ่มเติม

ตัวอย่างสดจริงจากข้อกำหนดRPM :

vim -E -s Makefile <<-EOF
   :%substitute/CFLAGS = -g$/CFLAGS =-fPIC -DPIC -g/
   :%substitute/CFLAGS =$/CFLAGS =-fPIC -DPIC/
   :%substitute/ADAFLAGS =$/ADAFLAGS =-fPIC -DPIC/
   :update
   :quit
EOF

แยกแท็ก html :

ex -s +'bufdo!/<div.*id=.the_div_id/norm nvatdggdG"2p' +'bufdo!%p' -cqa! *.html

การลบแท็ก XML :

ex -s +'%s/<[^>].\{-}>//ge' +%p +q! file.txt

การลบแท็กสไตล์ออกจากส่วนหัวและพิมพ์เอาต์พุตแยกวิเคราะห์:

curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin

แยกวิเคราะห์ HTMLด้วยกฎที่ซับซ้อนหลายรายการ:

ex -V1 $PAGE <<-EOF
  " Correcting missing protocol, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,'//,'http://,ge
  %s,"//,"http://,ge
  " Correcting relative paths, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,[^,]\zs'/\ze[^>],'http://www.example.com/,ge
  %s,[^,]\zs"/\ze[^>],"http://www.example.com/,ge
  " Remove the margin on the left of the main block. "
  %s/id="doc_container"/id="doc_container" style="min-width:0px;margin-left : 0px;"/g
  %s/<div class="outer_page/<div style="margin: 0px;" class="outer_page/g
  " Remove useless html elements. "
  /<div.*id="global_header"/norm nvatd
  wq " Update changes and quit.
EOF

ตัวอย่างเพิ่มเติม:


ดูสิ่งนี้ด้วย:



5
นี่คือUUOC ; เพียงใช้vim '+:0,$s/foo/test/g' '+:wq! file2' file1แทน
Doorknob

2
หมายเหตุว่าอย่างน้อยบางส่วนของตัวอย่างเหล่านี้จะไม่ POSIX bufdoสอดคล้องตัวอย่างเช่น แม้ว่าจะเป็นกลุ่มเป็นสิ่งที่ติดตั้งแทบทุกที่มันคุ้มค่ารู้ว่าคุณสามารถแฟ้มสคริปต์การแก้ไขโดยใช้เพียงคุณสมบัติ POSIX exสอดคล้องของ
สัญลักษณ์แทน

คำถามและคำตอบนี้เป็นสิ่งที่เป็นแรงบันดาลใจให้ฉันพิจารณาexและเรียนรู้มันเป็นครั้งแรก ขอขอบคุณ. บางคนอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ (เปิดเผยเต็ม: ผมเขียนเหล่านี้;) คือการย้อนกลับของทุกสี่เส้นที่มีexและใช้-cตัวเลือก คุณอาจเพิ่มลงในรายการลิงก์ของคุณที่ด้านล่างหากคุณต้องการ :)
สัญลักษณ์แทน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.