2012-04-06 8 views
6

Normalerweise verwende ich wie diesesoffen vi mit geben Dateinamen

$ find -name testname.c 
./dir1/dir2/testname.c 
$ vi ./dir1/dir2/testname.c 

es ärgerlich ist wieder Dateinamen mit dem Standort eingeben.

Wie kann ich dies mit nur einem Schritt tun?

Ich habe

versucht
$ find -name testname.c | xargs vi 

aber ich gescheitert.

+0

Mögliche Duplizierung: http://stackoverflow.com/questions/5955577/bash-automatically-capture-output-of-last -executed-command-in-a-variable –

+0

Diese Antwort erklärt, warum die 'xargs' Lösung nicht funktioniert: [Warum sucht" locate filename | xargs vim "verursacht seltsames Terminalverhalten?" (http://stackoverflow.com/a/8228888/85371) – sehe

Antwort

10

Verwenden Sie den -exec Parameter zu find.

$ find -name testname.c -exec vi {} \; 

Wenn Ihr find kehrt mehrere obwohl einstimmt, werden die Dateien nacheinander geöffnet werden. Das heißt, wenn Sie einen schließen, wird der nächste geöffnet. Sie werden sie nicht alle in Puffern aufstellen.

Um sie alle zu öffnen in Puffer zu erhalten, verwenden:

$ vi $(find -name testname.c) 

Ist das wirklich vi, nebenbei bemerkt, und nicht Vim, um heute welche vi oft aliased?

+0

Hinzufügen eines + statt \; zu finden wäre besser zum Öffnen mehrerer Dateien. + Syntax wird von POSIX definiert und sollte verfügbar sein. – jordanm

4

Das Problem ist xargs übernimmt alle vi ‚s Eingang dort (und keine andere Möglichkeit hat, dann geht auf /dev/null-vi weil die Alternative, den Rest der Dateiliste ist vorbei), für Sie keine Möglichkeit verlassen zu interagieren mit ihm. Sie wollen wahrscheinlich stattdessen einen Unterbefehl verwenden:

$ vi $(find -name testname.c) 

Leider gibt es keinen einfachen fc oder r Aufruf, die dies für Sie leicht tun können, nachdem Sie die ersten find ausgeführt haben, obwohl es leicht genug ist, um die Zeichen sowohl hinzufügen Ende des Befehls nach der Tat.

+0

kann ich dich etwas fragen ?. Sie meinen, dass 'xargs' in diesem Beispiel nicht nur das'./dir1/dir2/testname.c' übergeben? –

+0

Dateideskriptoren werden vererbt; normalerweise "vi" erbt seine Eingabe von der Shell, deren Eingabe Ihr Terminal ist, aber wenn Sie 'xargs' am Ende einer Pipeline verwenden, wäre die geerbte Eingabe die Pipeline. 'xargs' will die Pipeline nicht dem laufenden Programm geben (da es im besten Fall eine konsumierte Pipeline weitergibt und im schlimmsten Fall das Programm eine Eingabe für' xargs' konsumieren würde), also ersetzt es '/ dev/null'. – geekosaur

3

Meine Lieblings Lösung ist vim selbst zu verwenden:

:args `find -name testname.c` 

Übrigens hat VIM erweitert Schale Globbing builtin, so kann man nur sagen,

:args **/testname.c 

die rekursiv im Unterverzeichnisbaum finden .

nicht auch hat, dass VIM Vervollständigung von Dateinamen auf der Kommandozeile, also, wenn Sie wissen, dass Sie wirklich für eine einzelne Datei suchen, versucht

:e **/test 

und drücken Sie dann Tab (wiederholt), um zwischen jedem Matchin Dateinamen im Unterverzeichnisbaum.

1

Für etwas etwas robuster als vi $(find -name testname.c) und dergleichen, schützt das folgende gegen Dateinamen mit Leerzeichen und anderen interpretierten Shell-Zeichen (wenn Sie Zeilenumbrüche in Ihre Dateinamen eingebettet haben, Gott helfen Ihnen). Injizieren Sie diese Funktion in Ihre Shell-Umgebung:

# Find a file (or files) by name and open with vi. 
function findvi() 
{ 
    declare -a fnames=() 
    readarray -t fnames < <(find . -name "$1" -print) 
    if [ "${#fnames[@]}" -gt 0 ]; then 
     vi "${fnames[@]}" 
    fi 
} 

Dann nutzen wie

$ findvi Classname.java