Jak mogę otworzyć plik wynikający z grep?

17

Często grepuje kilka plików, aby znaleźć linię, a następnie grep zwraca jeden wynik. Zamiast kopiować i wklejać nazwę pliku do nowego polecenia, chciałbym móc otworzyć ten wynik w edytorze. Coś jak: grep foo | vim. Czy jest na to sposób w BASH?

Jonathan
źródło
5
Byliście raczej blisko, po prostu powiedzcie, vimżeby przeczytać STDIN:grep foo | vim -
devnull
2
Zobacz także unix.stackexchange.com/q/110146/22565
Stéphane Chazelas

Odpowiedzi:

20

Użyj, grep -laby pobrać nazwę pasującego pliku, a nie pasujący tekst, a następnie połączyć go z vim:

vim "$(grep -l some_pattern file_names)"
Anthon
źródło
Dodatkowo możesz użyć -qflagi of, grepaby upewnić się, że grep rzeczywiście doprowadził do jakiegoś pasującego pliku:grep -q patterns fnames && vim $(grep -l pattern fnames)
mkc
Czy powinienem zwrócić uwagę na nazwy plików ze spacjami?
Bernhard
@Bernhard To nigdy nie zaszkodzi, a także o tych z nowymi liniami i innymi postaciami specjalnymi. Ja rozpoznać problem, kiedy vinarzeka, PO nie może.
Anthon
Nie działa, jeśli dopasowane pliki mają spacje na swojej ścieżce
psuzzi
5

Możesz używać quickfixlub funkcjonować errorfilew vim:

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

Vim otworzy pierwszy plik /tmp/foo.listi umieści kursor bezpośrednio w linii, w której foozostał znaleziony. Możesz przejść do następnej instancji za pomocą :cni poprzedniej instancji za pomocą :cp.

Uwaga dodatkowa : jeśli już używasz vimlub gvim, sugerowałbym użycie jego wbudowanej grepfunkcjonalności. Przeczytaj, :help vimgrepaby uzyskać więcej informacji.

Srinidhi
źródło
1

Do wyszukiwania w projekcie nie musisz zostawiać vima z Fugitive

autocmd QuickFixCmdPost *grep* cwindow

Poniżej możesz zobaczyć przykład :Ggrep config

wprowadź opis zdjęcia tutaj

goodniceweb
źródło
0

EDYCJA: Po przeczytaniu twojego komentarza zdaję sobie sprawę, że początkowo nie rozumiałem pytania. Oto prosty skrypt, który traktuje wyszukiwane hasło jako argument i monituje o ścieżkę wyszukiwania. Jeśli wynik zostanie znaleziony tylko w jednym pliku, plik zostanie otwarty do edycji w miejscu wyniku wyszukiwania.

#!/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
źródło
Ale wydaje się, że pozwala mi to edytować wyjście grep, ale chcę edytować plik o nazwie pliku zwracanej przez grep.
Jonathan
0

@devnull otrzymał odpowiedź w tym komentarzu:

Byłeś raczej blisko, po prostu powiedz vimowi, żeby przeczytał ze STDIN:

grep foo | vim -

Noumenon
źródło
0

Aby rozwinąć odpowiedź Anthona w przypadku, gdy masz więcej niż jedno dopasowanie, w niektórych przypadkach pomocne może być użycie head -1(z tej odpowiedzi ) wyboru tylko pierwszego wyniku:vim "$(grep -l STRING FILES|head -1)"

EL_DON
źródło
0

Jeśli wykonujesz długie polecenie, które ma grep gdzieś pośrodku, możesz to zrobić

vim `command1 | grep whatever | awk '{do_something_else}'`
Greg
źródło