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?
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?
Odpowiedzi:
Użyj, grep -l
aby 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)"
-q
flagi of, grep
aby upewnić się, że grep rzeczywiście doprowadził do jakiegoś pasującego pliku:grep -q patterns fnames && vim $(grep -l pattern fnames)
vi
narzeka, PO nie może.
Możesz używać quickfix
lub funkcjonować errorfile
w vim
:
$ grep -n foo * > /tmp/foo.list
$ vim -q /tmp/foo.list
Vim otworzy pierwszy plik /tmp/foo.list
i umieści kursor bezpośrednio w linii, w której foo
został znaleziony. Możesz przejść do następnej instancji za pomocą :cn
i poprzedniej instancji za pomocą :cp
.
Uwaga dodatkowa : jeśli już używasz vim
lub gvim
, sugerowałbym użycie jego wbudowanej grep
funkcjonalności. Przeczytaj, :help vimgrep
aby uzyskać więcej informacji.
Do wyszukiwania w projekcie nie musisz zostawiać vima z Fugitive
autocmd QuickFixCmdPost *grep* cwindow
Poniżej możesz zobaczyć przykład :Ggrep config
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
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)"
vim
żeby przeczytaćSTDIN
:grep foo | vim -