เปิดไฟล์ที่กำหนดโดยผลลัพธ์ของคำสั่งเป็นกลุ่ม


34

ฉันพบว่าตัวเองทำสิ่งต่อไปนี้เกือบทุกวัน

  1. เรียกใช้การค้นหา ( find -name somefile.txt)
  2. เปิดผลลัพธ์ vim

ปัญหาคือฉันต้องคัดลอกและวางผลลัพธ์ของการfindลงในvimคำสั่ง มีวิธีหลีกเลี่ยงการทำเช่นนี้หรือไม่? ฉันได้ทดลองเล็กน้อย ( find -name somefile.txt | vim) แต่ไม่พบสิ่งใดที่ใช้งานได้

ขอบคุณล่วงหน้า

คำตอบ:


31

คุณสามารถใช้การทดแทนคำสั่ง:

vim $(find -name somefile.txt)

หรือ

find -name somefile.txt -exec vim {} \;

1
ตกลง. หากนั่นคือสิ่งที่จำเป็นให้ค้นหา -name somefile.txt | xargs vim
balki

3
ไม่มันทำงานไม่ถูกต้องและอาจทำให้เครื่องของคุณยุ่งเหยิง! คุณไม่สามารถไพพ์ไปยัง xargs vim ได้เนื่องจาก vim คาดว่าอินพุตจะมาจากเทอร์มินัลเชิงโต้ตอบ
dogbane

1
ผู้ใช้ที่ไม่ระบุชื่อบันทึกว่าสิ่งนี้จะล้มเหลวหากชื่อไฟล์มีช่องว่าง
Michael Mrozek

4
ทางเลือกอื่นก็vim `find -name somefile.txt`คือ @StuartPowers หรือคุณสามารถใช้vim `!-1`ถ้าคุณใช้แล้วพบนี้เป็นคำสั่งก่อนหน้าคุณ
เบอร์นาร์ด

1
@balki ใช้ xargs ในสถานการณ์นี้คุณต้องใช้แฟล็ก -o ซึ่งอยู่ใน man: -o เปิด stdin อีกครั้งเป็น / dev / tty ในกระบวนการ child ก่อนดำเนินการคำสั่ง สิ่งนี้มีประโยชน์หากคุณต้องการให้ xargs เรียกใช้แอปพลิเคชันแบบโต้ตอบ
davidmh

7

ลองสิ่งนี้:

  1. เริ่มเป็นกลุ่ม
  2. ในกลุ่มให้ใช้สิ่งต่อไปนี้:

:r!find /<path> -name 'expression'

ผลลัพธ์ควรปรากฏเป็นกลุ่มเมื่อการค้นหาเสร็จสมบูรณ์

หรือ

ลอง:

find /<path> -name > results.txt
vim results.txt 

โซลูชันของฉันเหมือนกันทุกประการ แต่ทำไมลงคะแนนฉัน
balki

5

หากคุณไม่รังเกียจที่จะเรียกใช้คำสั่งอีกครั้ง: กดUpและผนวกxargsคำสั่ง หรือใช้การทดแทนประวัติและเรียกใช้

!! | xargs vim          # won't work with file names containing \'" or whitespace
!! | xargs -d \\n vim   # GNU only (Linux, Cygwin)

มีวิธีที่มีน้ำหนักเบาในการบันทึกเอาต์พุตของคำสั่งที่ทำงานใน ksh และ zsh แต่ไม่ได้อยู่ใน bash (ต้องใช้ด้านเอาต์พุตของไพพ์ไลน์ที่จะเรียกใช้งานในพาเรนต์เชลล์) ท่อคำสั่งเข้าสู่ฟังก์ชั่นK(ความคมชัด zsh ด้านล่าง) ซึ่งk eeps $Kผลผลิตของตนในตัวแปร

function K {
    K=("${(@f)$(tee /dev/fd/3)}") 3>&1;
}
find  |K
vim $K

การบันทึกเอาต์พุตของแต่ละคำสั่งโดยอัตโนมัตินั้นไม่สามารถทำได้กับเชลล์เพียงอย่างเดียวคุณจำเป็นต้องรันคำสั่งในเทอร์มินัลที่จำลอง คุณสามารถทำได้โดยทำงานภายในscript(ยูทิลิตี้ BSD แต่มีอยู่ใน unices ส่วนใหญ่รวมถึง Linux และ Solaris) ซึ่งจะบันทึกผลลัพธ์ทั้งหมดของเซสชันของคุณผ่านไฟล์ )


2

ฉันชอบที่จะใช้เครื่องหมายขีดหลัง `(บนคีย์เดียวกันกับ ~)

> vim `find . -name somefile.txt`

ด้านหลังเห็บดำเนินการคำสั่งภายในเครื่องหมายและจากนั้นสามารถนำมาใช้โดยคำสั่ง ด้านบนจะค้นหาไฟล์ทั้งหมด somefile.txt ซึ่งจะช่วยให้คุณ:nextสามารถเลื่อนดูไฟล์ทั้งหมดได้

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

> find . -name somefile.txt
./debug/somefile.txt
./somefile.txt
> vi `!!`

2

ฉันต้องพลาดจุดที่นี่เพราะฉันจะใช้:

:find **/somefile.txt

(ถ้าฉันรู้ว่ามีเพียงหนึ่งในฉัน :echo &path ) หรือถ้าฉันต้องการพวกเขาทั้งหมด:

:args **/somefile.txt

แก้ไข: โอ้โห! ตกลงดังนั้นฉันไม่พลาดจุด - คุณต้องการหารายชื่อไม่ไฟล์จริงเปิด? ลอง (อีกครั้งจากภายในเป็นกลุ่ม):

!!find . -name somefile.txt

-- ความผิดฉันเอง :)


1

@davidmh ชี้ไปที่ความคิดเห็นคุณสามารถใช้xargsกับธง-oหากคุณต้องการใช้แอปพลิเคชันแบบโต้ตอบ

find . -name somefile.txt | xargs -o vim

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

reset

0

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

stu@sente ~ $ function pvim() { read -r somefile; exec < /dev/fd/1; vim "$somefile"; }
stu@sente ~ $ type pvim
pvim is a function
pvim ()
{
    read -r somefile;
    exec < /dev/fd/1;
    vi "$somefile"
}

ใช้มันเหมือน:

stu@sente ~ $ find . -name "foo.txt" | pvim

ซึ่งจะโหลด "foo.txt" อันแรกลงในเสียงเรียกเข้าเสมือนว่าคุณพิมพ์:

vim $(find . -name "foo.txt | head -n1")


0

นี่เป็นวิธีที่ง่ายxargsกว่าที่กล่าวไว้แล้ว:

find -name somefile.txt | xargs vim -p

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


0

ฉันพบว่าการเปิดไฟล์โดยใช้locatevim นั้นสะดวกและเร็วกว่าfindมาก

คำสั่งต่อไปนี้ค้นหาไฟล์ที่เรียกว่าอยู่ในเส้นทางที่มีไดเรกทอรีapp.pyMyPythonProject

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