ฉันจะแก้ไขไฟล์ทั้งหมดที่ส่งคืนโดย find in vi ใน Linux ได้อย่างไร?


27

สิ่งที่ฉันพบว่าตัวเองกำลังทำอะไรมากกำลังรันคำสั่ง find จากนั้นแก้ไขคำสั่งทั้งหมดใน vi ซึ่งมีลักษณะดังนี้:

> find . "*.txt"
./file1.txt
./file2.txt
./path/to/file3.txt

> vi ./file1.txt ./file2.txt ./path/to/file3.txt

มีวิธีที่ฉลาดและเรียบง่ายในการทำสิ่งนี้ทั้งหมดในบรรทัดคำสั่งเดียวหรือไม่?


1
คุณสามารถไพพ์ลงใน vi: find "* .txt" | xargs vi
MaQleod

1
@MaQleod: เทคนิคมันจะเป็นท่อที่จะxargs
grawity


ท่อไปxargsทำลายขั้วเปลือกของฉัน วิธีการแก้ปัญหาที่เหมาะสมคือหนึ่งในด้านล่างโดย @DevSolar
typelogic

คำตอบ:


41

สิ่งนี้ควรทำเคล็ดลับ:

find . -name "*.txt" -exec vim {} + 

ใช้เป็นกลุ่มจะดีกว่าเพื่อสุขภาพของคุณ :-)

+ตัวเลือกที่มองข้ามเพื่อ-execทำให้ชื่อไฟล์ทั้งหมด (สูงสุดถึงขีดจำกัดความยาวบรรทัด) ปรากฏในบรรทัดเดียวนั่นคือคุณยังคงเปิดไฟล์ทั้งหมดในเซสชันเดียว vim (สำรวจด้วยไฟล์:nถัดไปและ:Nไฟล์ก่อนหน้า)

เมื่อvim -pคุณได้รับแท็บไฟล์สำหรับแต่ละไฟล์ ตรวจสอบ:help tab-page-commandsรายละเอียดเพิ่มเติม

ด้วยvim -oคุณจะได้รับ windows ที่แยกตามแนวนอนสำหรับแต่ละไฟล์vim -Oแยก windows ในแนวตั้ง ตรวจสอบ:help window-move-cursorรายละเอียดเพิ่มเติม

โปรดทราบว่าเวอร์ชันก่อนหน้าของคำตอบนี้ใช้vim $(find . -name "*.txt")ไม่ได้กับช่องว่างในชื่อไฟล์และมีผลกระทบด้านความปลอดภัย

การเข้าไปในท่อxargs viจะให้ a Warning: Input is not from a terminalและเทอร์มินัลที่มีพฤติกรรมปลอมอย่างสมบูรณ์ในภายหลัง grawity ของผู้ใช้อธิบายว่าทำไมในความคิดเห็นด้านล่างและมีคำอธิบายเพิ่มเติมเล็กน้อยในคำถามนี้


4
ไม่ทราบจำนวนที่คุณรู้เกี่ยวกับเสียงเรียกเข้า แต่ใช้ฉัน / ตลอดไป / เพื่อหาว่า: n แสดงไฟล์ถัดไปและ: N แสดงไฟล์ก่อนหน้า
zpletan

4
@DevSolar: Vim คาดว่า stdin นั้นจะเหมือนกับเทอร์มินัลการควบคุมและดำเนินการ ioctls ที่เกี่ยวกับเทอร์มินัลต่างๆบน stdin โดยตรง (คุณสามารถพิจารณาข้อผิดพลาดนี้เป็นกลุ่มแน่นอนสามารถเปิด/dev/ttyและเรียก ioctl () ที่มันขี้เกียจเกินไปที่จะทำมัน) เมื่อเรียกโดย xargs, VIM ได้รับ/dev/nullเป็นอินพุตมาตรฐานซึ่งเพียงละเว้น ioctls เทอร์มินัลการควบคุม
grawity

3
@zpletan: vim -pหากคุณต้องการแท็บไฟล์ ( gtและgTเพื่อนำทางหรือคลิกด้วยเมาส์ของคุณ)
grawity

2
FYI เพื่อหลีกเลี่ยงการเตือนเมื่อเข้าสู่ท่อvimเพียงระบุเป็นอาร์กิวเมนต์แรกในขณะที่- echo foobar | vim -
Konrad Rudolph

2
@ Konrad Rudolph: find . -name "*.txt" | vim -ให้คุณเป็นกลุ่มที่มีชื่อไฟล์ที่มีชื่อของไฟล์ที่พบซึ่งไม่ใช่สิ่งที่ OP ขอ ...
DevSolar


1

นอกจากนี้หากคุณต้องการให้พวกเขาเปิดทีละครั้งคุณยังสามารถใช้ find -exec หรือใช้แบบง่ายสำหรับลูป แก้ไขต่อความคิดเห็นของ ceving

find . -name "*.txt" -exec vi {} \;

หรือ

OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `find . -name "*.txt"`
    do
        vi $i
    done
IFS=$OLDIFS

... แต่ทำไมคุณถึงต้องการทำเช่นนั้น?
DevSolar

@DevSolar อันแรกคือการชี้ให้เห็นความสามารถในการค้นหาที่สองคือวงวนวัตถุประสงค์ทั่วไป บางทีคุณอาจต้องการทำบางสิ่งกับทุกไฟล์ก่อนที่จะแก้ไข
OldWolf

คุณเคยลองครั้งที่สองหรือไม่? ก่อนอื่น: การค้นหาส่งคืนไดเรกทอรีปัจจุบันเนื่องจาก-nameไม่มีอยู่ และที่สอง: คำสั่งล้มเหลวอย่างน่าสังเวชทันทีที่ชื่อไฟล์มีช่องว่าง -1 สำหรับคำตอบที่ไม่เหมาะสม
ceving

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

@ceving จุดที่ถูกต้อง ฉันสันนิษฐานว่าผู้โพสต์ต้นฉบับพบว่าถูกต้องสำหรับความต้องการของเขา การแก้ไข
OldWolf

0

หากคุณพิมพ์findคำสั่งของคุณแล้วฉันพบว่ามันสามารถใช้งานได้ง่ายกว่ามากในxargsการเปิดผลการค้นหา:

find . -name "*.txt" | xargs vim -p

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


ขอบคุณฉันเชื่อมต่อมันเพื่อค้นหาคำสั่งของฉันคือ: ค้นหาชื่อไฟล์ | xargs vim -p
talsibony

0

หากต้องการแก้ไขทั้งหมดคุณสามารถเรียกใช้เพียง:*.txt vim *.txtหากต้องการแก้ไขไฟล์ที่ส่งคืนโดยfindให้อ่านเพิ่มเติม


บน Unix / macOS คุณสามารถใช้findกับ BSD xargs(ดูman xargs:) เช่น

find -L . -name "*.txt" -type f -print0 | xargs -o -0 vim

-o( xargs): เปิด stdin อีกครั้งเป็น / dev / tty ในกระบวนการลูกก่อนดำเนินการคำสั่ง

ที่เกี่ยวข้อง: เทอร์มินัล borked หลังจากเรียกใช้ Vim ด้วย xargsที่ Vim.SE

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