วิธี `ค้นหา 'หลายไฟล์และเปิดในกลุ่ม?


10

สมมติว่าผมมีไฟล์ชื่อfilename123.txtและเป็นไฟล์เดียวที่มีชื่อเช่นนั้นและฉันสามารถกับคำสั่งlocate locate filename123และจะส่งคืนเฉพาะไฟล์นี้

ตอนนี้ผมต้องการที่จะเปิดมันด้วย/vi vimแต่ฉันไม่ต้องการไปที่ตำแหน่งนั้นและพิมพ์viคำสั่งตามด้วยชื่อไฟล์ ที่นี่ฉันต้องการผลลัพธ์locate filename123ที่จะผนวกเข้ากับคำสั่ง vi ฉันจะทำเช่นนั้นได้อย่างไร ฉันได้ลองแล้ว:

locate filename123 | vi

แต่มันไม่ได้ผล และข้อผิดพลาดนี้มาใน terminal:

santosh@santosh:~$ locate filename123 | vi
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: Finished.

คำตอบ:


12

คุณสามารถใช้xargs:

locate filename123 | xargs vi

โดยค่าเริ่มต้นxargsจะดำเนินการเป็นเพียงกรณีของคำสั่งที่ระบุเป็นไปได้ผ่านเป็นพารามิเตอร์ที่เป็นไปได้มากที่สุดเท่าที่เป็นไปตามระบบARG_MAX หากต้องการ จำกัด จำนวนพารามิเตอร์ที่ส่งไปยังอินสแตนซ์ของviให้ใช้ตัวเลือกxargs'-n

ในการจัดการชื่อไฟล์ที่มีช่องว่างให้ใช้ตัวเลือกxargs' -d:

locate filename123 | xargs -d '\n' vi

เพื่อจัดการกับชื่อไฟล์ที่มีการขึ้นบรรทัดใหม่ใช้xargs' -0ตัวเลือกร่วมกับlocate' s -0ตัวเลือก:

locate -0 filename123 | xargs -0 vi

(หาก-0ไม่มีอยู่ในรายการใด ๆ ให้ตรวจสอบ--nullด้วยหรืออีกวิธีหนึ่งในการระบุอักขระ\000เป็นตัวคั่น)


คุณช่วยบอกฉันได้ว่าอะไรคือสิ่งที่ป้องกันฉันก่อนที่จะเปิดไฟล์นี้?
Santosh Kumar

1
@Santosh คุณส่งเอาต์พุตของlocateคำสั่งเป็นอินพุตไปที่ vi Vi เช่นเดียวกับโปรแกรมอื่น ๆ คาดว่าชื่อของไฟล์จะทำงานเป็นอาร์กิวเมนต์
Gilles 'หยุดความชั่วร้าย'

@ การจัดการปัญหาคือฉันไม่สามารถค้นหาและเปิดชื่อไฟล์ที่มีช่องว่างในนั้น เช่นคำสั่งนี้จะเปิดไฟล์หลายไฟล์ในกลุ่ม: ค้นหา I \ have \ to \ download | xargs vi
Santosh Kumar

3

คุณสามารถใช้การขยายคำสั่ง:

vi "$(locate filename123 | head -n1)"

หากต้องการvimอ่าน stdin ของมันคุณสามารถทำได้vim -แต่นั่นจะให้ผลลัพธ์locateที่เป็นเส้นทางชื่อไฟล์ สิ่งนี้อาจใช้ได้แม้ว่าการใช้vim gfคำสั่งปกติจะเปิดเส้นทางที่เคอร์เซอร์เปิดอยู่

แก้ไข

ในกรณีของชื่อไฟล์ที่มีช่องว่างคุณควรใช้xargsตัวเลือกที่กล่าวถึงหรือvimวิธีการแก้ปัญหาที่อธิบายไว้ข้างต้น หมายเหตุเพื่อให้gfงานคุณต้องเพิ่มพื้นที่ในisfname:

set isfname+=32

เคล็ดลับนี้และทางเลือกจะมีคำอธิบายที่นี่

แก้ไข 2

เพิ่มคำพูดและheadการแนะนำโดย Petero ในการแสดงความคิดเห็น


สำหรับไฟล์ที่มีช่องว่างอยู่ในนั้นเมื่อฉันใส่ \ in ชื่อไฟล์เช่น vi $ (ค้นหาอีก \ ไฟล์) เสียงเรียกเข้าดังกล่าวจะเปิดเป็นสองไฟล์แยกกันanotherและfile:(.
Santosh Kumar

คำตอบของคุณใช้ได้เฉพาะเมื่อฉันไม่มีที่ว่างในไฟล์ที่ฉันค้นหา
Santosh Kumar

อัปเดตคำตอบแล้ว
ธ.ค.

2
@Thor: สำหรับไฟล์เดียวตามที่กล่าวถึงในคำถามคุณเพียงแค่ต้องใส่เครื่องหมายคำพูดรอบการทดแทนกระบวนการ: vi "$(locate filename123)"... เพื่อให้แน่ใจว่ามันมีชื่อไฟล์เดียวที่จะจัดการกับ:vi "$(locate filename123 |head -n1)"
Peter.O

PeterO: ถูกต้องฉันทดสอบกับเพลงฮิตหลายนัดเท่านั้น ฉันได้เพิ่มความคิดเห็นของคุณไปยังคำตอบ
Thor

1

วิธีที่ง่ายที่สุดคือการผ่านlocateเป็นเปลือกทดแทนเช่น:

vim $(locate filename123)

คุณสามารถพิจารณาใช้findแทนlocateการส่งชื่อไฟล์เพื่อแก้ไขตัวอย่าง:

find . -name 'filename123' -exec vim {} +

บน Unix / OSX คุณสามารถใช้xargsกับ-oพารามิเตอร์เช่น:

locate filename123 | xargs -o vim

-oเปิด stdin อีกครั้งเป็น / dev / tty ในกระบวนการ child ก่อนดำเนินการคำสั่ง สิ่งนี้มีประโยชน์หากคุณต้องการให้ xargs เรียกใช้แอปพลิเคชันแบบโต้ตอบ

หรือบน Linux ลองใช้วิธีแก้ปัญหาต่อไปนี้โดยใช้:

locate filename123 | xargs -J% sh -c 'vim < /dev/tty $@'

หากคุณใช้คำสั่งต่าง ๆ ให้ใช้การแทนที่คำสั่งเพื่อให้ได้ผลลัพธ์เช่น:

vim $(locate filename123)
vim `locate filename123`

หรือใช้ GNU parallelแทนxargsบังคับให้จัดสรร tty ตัวอย่างเช่น:

locate filename123 | parallel -X --tty vi

หมายเหตุ: parallelบน Unix / OSX จะไม่ทำงานเนื่องจากมีพารามิเตอร์ที่แตกต่างกันและไม่รองรับ tty

คำสั่งยอดนิยมอื่น ๆ อีกมากมายให้การจัดสรรแบบหลอกเช่นกัน (เหมือน-tในssh) ดังนั้นตรวจสอบความช่วยเหลือ

ข้อเสนอแนะอื่น ๆ คือการใช้vipe(ไพพ์คำสั่ง Vim) หรือใช้สคริปต์อย่างง่ายต่อไปนี้:

#!/bin/sh
# usage: locate filename123 | vip
exec vim < /dev/tty "$@"

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

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