Wie kann ich eine Datei öffnen, die aus grep resultiert?

16

Ich greife oft nach einer Reihe von Dateien, um eine Zeile zu finden, und grep gibt dann ein Ergebnis zurück. Anstatt den Dateinamen zu kopieren und in einen neuen Befehl einzufügen, möchte ich dieses eine Ergebnis mit einem Editor öffnen können. Etwas wie: grep foo | vim. Gibt es eine Möglichkeit, dies in BASH zu tun?

Jonathan
quelle
5
Sie waren ziemlich nahe, einfach sagen vimaus zu lesen STDIN:grep foo | vim -
devnull
2
Siehe auch unix.stackexchange.com/q/110146/22565
Stéphane Chazelas

Antworten:

20

Verwenden Sie grep -ldiese Option, um nur den Dateinamen der übereinstimmenden Datei und nicht den übereinstimmenden Text abzurufen, und kombinieren Sie ihn dann mit vim:

vim "$(grep -l some_pattern file_names)"
Anthon
quelle
Darüber hinaus können Sie -qflag of verwenden grep, um sicherzustellen, dass grep tatsächlich zu einer übereinstimmenden Datei geführt hat:grep -q patterns fnames && vim $(grep -l pattern fnames)
mkc
Sollte ich eine Bemerkung zu Dateinamen mit Leerzeichen machen?
Bernhard
@Bernhard Es kann nie weh tun, und auch nicht bei solchen mit Zeilenumbrüchen und anderen Sonderzeichen. Ich erkenne das Problem, wenn visich das OP beschwert, vielleicht nicht.
Anthon
Funktioniert nicht, wenn übereinstimmende Dateien Leerzeichen im Pfad haben
psuzzi
5

Sie können verwenden quickfixoder errorfilein Funktion vim:

$ grep -n foo * > /tmp/foo.list
$ vim -q /tmp/foo.list

Vim öffnet die erste Datei in /tmp/foo.listund platziert den Cursor direkt in der Zeile, in fooder er gefunden wurde. Sie können mit zur nächsten :cnund mit zur vorherigen Instanz wechseln :cp.

Randnotiz : Wenn Sie bereits vimoder verwenden gvim, würde ich vorschlagen, die eingebaute grepFunktionalität zu verwenden. Lesen Sie :help vimgrepfür weitere Informationen.

Srinidhi
quelle
1

Für die Suche im Projekt müssen Sie vim nicht bei Fugitive lassen

autocmd QuickFixCmdPost *grep* cwindow

Unten sehen Sie ein Beispiel für :Ggrep config

Bildbeschreibung hier eingeben

goodniceweb
quelle
0

EDIT: Nachdem ich Ihren Kommentar gelesen habe, stelle ich fest, dass ich die Frage anfangs nicht verstanden habe. Hier ist ein einfaches Skript, das Ihren Suchbegriff als Argument verwendet und zur Eingabe des Suchpfads auffordert. Wenn das Ergebnis nur in einer Datei gefunden wird, wird die Datei zum Bearbeiten am Speicherort des Suchergebnisses geöffnet.

#!/bin/bash

SRCHTRM="$1"

read -p "Where to search: " SRCHPATH

FILEFOUND=$(grep "$SRCHTRM" $SRCHPATH)
FILEFOUNDCNT=$(grep "$SRCHTRM" $SRCHPATH | wc -l)

FILEAWK=$(echo "$FILEFOUND" | awk -F":" '{ print $1 }')

if [ "$FILEFOUNDCNT" -eq "1" ];then
    vi +/"$SRCHTRM" "$FILEAWK"
else
    echo "$1 was found in more than one file"
fi
Timothy Martin
quelle
Aber dies scheint mir zu ermöglichen, die Ausgabe von grep zu bearbeiten, aber ich möchte die Datei mit dem Dateinamen bearbeiten, den grep zurückgibt.
Jonathan
0

@devnull hat die Antwort in diesem Kommentar richtig verstanden:

Du warst ziemlich nah dran, sag einfach vim, dass er von STDIN lesen soll:

grep foo | vim -

Noumenon
quelle
0

Um Anthons Antwort für einen Fall zu erweitern, in dem Sie mehr als eine Übereinstimmung haben, kann es in einigen Fällen hilfreich sein, head -1(aus dieser Antwort ) nur das erste Ergebnis auszuwählen:vim "$(grep -l STRING FILES|head -1)"

EL_DON
quelle
0

Wenn Sie einen langen Befehl ausführen, in dessen Mitte grep steht, können Sie dies auch tun

vim `command1 | grep whatever | awk '{do_something_else}'`
Greg
quelle