Wie kann man mehrere Dateien finden und in vim öffnen?

10

Angenommen, ich habe eine Datei mit dem Namen filename123.txtund es ist die einzelne Datei, die so benannt ist, und ich kann locatees mit dem Befehl locate filename123. Und es wird nur diese Datei zurückgegeben.

Jetzt möchte ich es mit vi/ öffnen vim. Aber ich möchte nicht zu diesem Speicherort gehen und den viBefehl gefolgt von Dateiname eingeben. Hier möchte ich, dass das Ergebnis von locate filename123an den Befehl vi angehängt wird. Wie kann ich das machen? Ich habe es schon versucht:

locate filename123 | vi

Das geht aber nicht. Und dieser Fehler kommt im Terminal:

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

Antworten:

12

Sie können verwenden xargs:

locate filename123 | xargs vi

Standardmäßig xargswerden so wenige Instanzen des angegebenen Befehls wie möglich ausgeführt, wobei so viele Parameter wie möglich gemäß ARG_MAX des Systems übergeben werden . viVerwenden Sie xargsdie -nOption ', um die Anzahl der an eine Instanz von übergebenen Parameter zu begrenzen .

Verwenden Sie xargsdie -dOption ', um Dateinamen mit Leerzeichen zu verarbeiten :

locate filename123 | xargs -d '\n' vi

Um Dateinamen mit Zeilenumbrüchen zu behandeln, verwenden Sie xargsdie -0Option ' zusammen mit locateder -0Option':

locate -0 filename123 | xargs -0 vi

(Wenn -0auf keinem von ihnen eine Option verfügbar ist, überprüfen Sie dies --nullauch oder auf eine andere Weise, um ein Zeichen \000als Trennzeichen anzugeben .)

Mann bei der Arbeit
quelle
Können Sie mir sagen, was mich zuvor daran gehindert hat, diese Datei zu öffnen?
Santosh Kumar
1
@ Santosh Sie haben die Ausgabe des locateBefehls als Eingabe an vi übergeben. Vi erwartet, wie jedes andere Programm, dass der Name der Datei (en) als Argumente verwendet wird.
Gilles 'SO - hör auf böse zu sein'
@manatwork Das Problem ist, dass ich den Dateinamen mit Leerzeichen nicht finden und öffnen kann. Zum Beispiel öffnet dieser Befehl mehrere Dateien in vim: Suchen Sie I \ have \ to \ download | xargs vi
Santosh Kumar
3

Sie können die Befehlserweiterung verwenden:

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

Um das vimLesen zu erleichtern , können Sie dies tun vim -, aber das gibt Ihnen nur die Ausgabe von locateDateinamenpfaden. Dies kann jedoch funktionieren. Wenn Sie den vim gfnormalen Befehl verwenden, wird der Pfad geöffnet, auf dem sich der Cursor befindet.

Bearbeiten

Bei Dateinamen mit Leerzeichen sollten Sie die oben xargsgenannte Option oder die vimoben beschriebene Lösung verwenden. Hinweis, damit gfSie arbeiten können, müssen Sie Platz hinzufügen für isfname:

set isfname+=32

Dieser Tipp und Alternativen werden hier beschrieben .

Bearbeiten 2

Zitate hinzugefügt und headwie von PeterO in den Kommentaren vorgeschlagen .

Thor
quelle
Für Dateien mit Leerzeichen, wenn ich \ in den Dateinamen einfüge, wie z. B. vi $ (suchen Sie eine andere \ Datei). Das vim öffnet es als zwei separate Dateien anotherund file:(.
Santosh Kumar
Ihre Antwort funktioniert nur, wenn die gesuchte Datei keine Leerzeichen enthält.
Santosh Kumar
Antwort aktualisiert.
Thor
2
@Thor: Für eine einzelne Datei, wie in der Frage erwähnt, müssen Sie nur Anführungszeichen um die Prozessersetzung setzen: vi "$(locate filename123)"... Um sicherzustellen, dass nur ein Dateiname behandelt werden muss:vi "$(locate filename123 |head -n1)"
Peter.O
PeterO: Du hast recht, ich habe nur mit mehreren Treffern getestet. Ich habe Ihre Kommentare zur Antwort hinzugefügt.
Thor
1

Der einfachste Weg ist, locateals Shell-Substitution zu übergeben , wie:

vim $(locate filename123)

Sie können auch in Betracht ziehen, Dateinamen zum Bearbeiten zu verwenden, findanstatt sie locatezu übergeben. Beispiel:

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

Unter Unix / OSX können Sie verwenden , xargsmit -oParametern, wie zB:

locate filename123 | xargs -o vim

-oÖffnen Sie stdin als / dev / tty im untergeordneten Prozess erneut, bevor Sie den Befehl ausführen. Dies ist nützlich, wenn xargs eine interaktive Anwendung ausführen soll.

Oder versuchen Sie unter Linux die folgende Problemumgehung mit:

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

Wenn Sie verschiedene Befehle verwenden, verwenden Sie die Befehlssubstitution , um dies zu erreichen, z.

vim $(locate filename123)
vim `locate filename123`

Verwenden Sie alternativ GNU , um die Zuweisung parallelvon xargstty zu erzwingen. Beispiel:

locate filename123 | parallel -X --tty vi

Hinweis: Unter parallelUnix / OSX funktioniert es nicht, da es unterschiedliche Parameter hat und tty nicht unterstützt.

Viele andere beliebte Befehle bieten ebenfalls eine Pseudo-Tty-Zuweisung (wie -tin ssh). Suchen Sie daher nach Hilfe.

Ein anderer Vorschlag wäre, eine vipe(Vim-Befehlspipe) oder das folgende einfache Skript zu verwenden:

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

Verbunden:

Kenorb
quelle