Wie kann ich alle von find in vi in ​​Linux zurückgegebenen Dateien bearbeiten?

27

Etwas, was ich häufig tue, ist, einen Suchbefehl auszuführen und dann alle in vi zu bearbeiten, was ungefähr so ​​aussieht:

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

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

Gibt es eine clevere und einfache Möglichkeit, dies alles in einer Befehlszeile zu erledigen?

abeger
quelle
1
Sie können es in vi: find leiten. "* .txt" | xargs vi
MaQleod
1
@ MaQleod: Technisch wäre es Piping zu Xargs .
Grawity
Piping, um xargsmein Shell-Terminal zu zerstören. Die richtige Lösung ist die folgende von @ DevSolar
typelogic

Antworten:

41

Dies sollte den Trick machen:

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

Verwenden Sie Vim, es ist besser für Ihre Gesundheit. :-)

Die oft übersehene +Option -execlässt alle Dateinamen (bis zu Zeilenlängenbeschränkungen) in einer Zeile erscheinen, dh Sie erhalten weiterhin alle Dateien, die in einer vim Sitzung geöffnet wurden (navigiert mit :nfür die nächste und :Nfür die vorherige Datei).

Mit erhalten vim -pSie eine Registerkarte für jede Datei. Überprüfen Sie :help tab-page-commandsfür weitere Details.

Mit erhalten vim -oSie horizontal geteilte Fenster für jede Datei, vim -Overtikal geteilte Fenster. Überprüfen Sie :help window-move-cursorfür weitere Details.

Beachten Sie, dass die vorherige Version dieser Antwort vim $(find . -name "*.txt")nicht mit Leerzeichen in Dateinamen funktioniert und Auswirkungen auf die Sicherheit hat.

Piping in xargs vigibt ein Warning: Input is not from a terminal, plus ein Terminal mit komplett falschem Verhalten danach. User Grawity hat in einem Kommentar unten und in dieser Frage etwas ausführlicher erklärt, warum .

DevSolar
quelle
4
Ich weiß nicht, wie viel du über vim weißt, aber ich habe / ewig / gebraucht, um herauszufinden, dass: n die nächste Datei und: N die vorherige Datei zeigt.
Zpletan
4
@DevSolar: Vim erwartet, dass seine Standard-ID mit der des steuernden Terminals übereinstimmt, und führt verschiedene Terminal-bezogene Ioctls direkt für Standard-ID durch. (Sie können dies als einen Fehler betrachten. Vim kann auf jeden /dev/ttyFall ioctl () öffnen und aufrufen; dazu ist es einfach zu faul.) Wenn es von xargs aufgerufen wird, erhält vim /dev/nullals Standardeingabe, die nur Terminal-Control-Ioctls ignoriert.
Grawity
3
@zpletan: vim -pWenn Sie Dateiregisterkarten möchten. ( gtUnd um gTzu navigieren oder mit der Maus zu klicken.)
Grawity
2
Um die Warnung beim Einleiten zu vermeiden vim, geben Sie einfach -wie in als erstes Argument an echo foobar | vim -.
Konrad Rudolph
2
@Konrad Rudolph: find . -name "*.txt" | vim -gibt Ihnen eine Vim-Sitzung für eine unbenannte Datei mit den Namen der gefundenen Dateien, was nicht das ist, wonach das OP gefragt hat ...
DevSolar
4

Oder laufen Sie vim und von dort:

:args **/*.txt
Benoit
quelle
1

Wenn Sie möchten, dass sie einzeln geöffnet werden, können Sie auch find -exec oder eine einfache for-Schleife verwenden. Bearbeitet nach Cevings Kommentar.

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

oder

OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `find . -name "*.txt"`
    do
        vi $i
    done
IFS=$OLDIFS
OldWolf
quelle
... aber warum willst du das machen?
DevSolar
@ DevSolar Die erste ist, um auf die Fähigkeit in find hinzuweisen, die zweite ist eine Mehrzweckschleife. Vielleicht möchten Sie jede Datei bearbeiten, bevor Sie sie bearbeiten.
OldWolf
Hast du schon mal den zweiten ausprobiert? Erstens: Die Suche gibt das aktuelle Verzeichnis zurück, da -namees fehlt. Und zweitens: Der Befehl schlägt kläglich fehl, sobald ein Dateiname ein Leerzeichen enthält. -1 für eine schlecht beratene Antwort.
16.
Eigentlich gilt das Thema Leerzeichen in Dateinamen auch für meine Antwort. Ich kann mir nicht einmal vorstellen, wie ich sie richtig handhaben könnte, ohne sie von einer Befehlszeile in ein eigenes kleines Skript umzuwandeln. Es gibt einen guten Grund, warum Leerzeichen in Dateinamen nicht empfohlen werden.
DevSolar
@ceving Ein gültiger Punkt. Ich nahm an, dass der Original-Poster-Fund für seine Bedürfnisse gültig war. Bearbeitung.
OldWolf
0

Wenn Sie Ihren findBefehl bereits eingegeben haben, ist das xargsÖffnen der Suchergebnisse möglicherweise viel einfacher :

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

Die -pOption weist vim an, jede Datei in einer neuen Registerkarte zu öffnen. Ich finde das praktischer als die Verwendung von Puffern, aber wenn nicht, lassen Sie diese Option einfach weg.

Cory Klein
quelle
Ich danke Ihnen, dass ich es angeschlossen habe, um zu lokalisieren xargs vim -p
talsibony
0

So bearbeiten Sie alle *.txtkönnen Sie einfach laufen: vim *.txt. findLesen Sie weiter, um die von zurückgegebenen Dateien zu bearbeiten .


Unter Unix / macOS können Sie findBSD verwenden xargs(siehe:) man xargs, z

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

-o( xargs): Öffnen Sie stdin als / dev / tty im untergeordneten Prozess, bevor Sie den Befehl ausführen.

Siehe auch : Das Terminal wurde nach dem Aufrufen von Vim mit xargs auf Vim.SE gesprengt.

Kenorb
quelle