Chcę wyszukać ciąg tekstu we wszystkich plikach w katalogu (a nie w jego podkatalogach; wiem, że -r
opcja to robi, ale nie tego chcę).
Bieganie
grep "string" /path/to/dir
powinienem to zrobić, przeczytałem, ale daje mi to błąd:
grep: dir: to katalog
Następnie próbowałem uruchomić
grep
na wielu plikach.grep "string" .bashrc .bash_aliases
działa świetnie.grep "string" .bash*
działa również zgodnie z przeznaczeniem.grep "string" *
daje mi błędy:grep: data: Is a directory grep: Desktop: Is a directory grep: Documents: Is a directory grep: Downloads: Is a directory ...
Drukowane są tylko błędy, nie otrzymuję pasujących linii. Próbowałem użyć tej -s
opcji, ale bezskutecznie.
Więc moje pytania:
Dlaczego nie mogę korzystać
grep
z katalogu, jak w (1), kiedy powinienem? Widziałem to w wielu przykładach w Internecie.
Edycja : Kiedy mówię „używając grep w katalogu”, mam na myśli „szukaj we wszystkich plikach w tym katalogu oprócz jego podkatalogów”. Uważam, że to właśnie robi grep, gdy przekazujesz do niego katalog zamiast pliku. Czy jestem w błędzie?Proszę o wyjaśnienie działania
grep
, które wyjaśniłoby zachowanie poleceń w (2).
Edycja : Pozwól mi być bardziej szczegółowy. Dlaczego za pomocą symboli wieloznacznych określa się wiele plików, w których ma być wyszukiwana praca,.bash*
a*
nawet nie, a nawet./*
?Jak mogę wyszukiwać wszystkie pliki w katalogu (a nie w jego podkatalogach) za pomocą
grep
?
*
Opierasz się również na znakach wieloznacznych rozszerzających powłoki, takich jak globbing. Globowanie nie obejmuje nazw plików rozpoczynających się od kropki, takiej.bashrc
jak standardowa. Możesz ustawić opcje powłoki, aby zawierały te pliki, ale możesz wpaść w bałagan, jeśli nie wiesz, co robisz. Dobry przewodnik po zrozumieniu globowania można znaleźć tutaj mywiki.wooledge.org/globgrep "string" .bash*
również z .grep "string" * .* 2>/dev/null
lubgrep -s "string" * .*
Odpowiedzi:
W Bash glob nie będzie rozwijał się do ukrytych plików, więc jeśli chcesz przeszukać wszystkie pliki w katalogu, musisz określić pliki ukryte
.*
i nie ukryte*
.Aby uniknąć błędów „Czy katalog”, możesz użyć
-d skip
, ale w moim systemie również pojawia się błądgrep: .gvfs: Permission denied
† , więc sugeruję użycie-s
, które ukrywa wszystkie komunikaty o błędach.Polecenie, którego szukasz, to:
Jeśli szukasz plików w innym katalogu:
Inną opcją jest użycie
dotglob
opcji powłoki, która sprawi, że glob będzie zawierać ukryte pliki.W przypadku plików w innym katalogu:
† Ktoś wspomniał, że nie powinienem dostać tego błędu. Mogą mieć rację - przeczytałem trochę, ale sam nie mogłem zrobić głów ani ogonów.
źródło
*
i.*
?echo * .*
iecho *.*
uruchom w swoim katalogu domowym, a różnica powinna być oczywista. W przeciwnym razie LMK i wyjaśnię to.echo *
pokazuje nie ukryte pliki i foldery,echo *.*
pokazuje nie ukryte pliki,echo .*
pokazuje wszystkie pliki iecho * .*
pokazuje wszystkie pliki i katalogi. Ale dlaczego powód odstępu między nimi w tym drugim przypadku? Czuję się niechlujny. Czy nie ma sposobu na połączenie tych dwóch, aby uzyskać takie same wyniki? Czy w przeciwnym razie istnieje wyjaśnienie składniowe, dlaczego należy je tutaj rozdzielić, czy też jest* .*
to wyjątkowy przypadek?*
reprezentuje wszystkie nie ukryte pliki (tzn. Nazwy plików, które nie zaczynają się od kropki);.*
reprezentuje wszystkie ukryte pliki (czyli nazwy plików, które nie zaczynają się od kropki); i*.*
reprezentuje wszystkie nie ukryte pliki zawierające kropkę. Wecho * .*
te dwa globs muszą być oddzielone, ponieważ są one różne globs: jeden dla non-ukryte, jeden dla ukryty. Chociaż, jak napisałem w mojej odpowiedzi, możesz włączyć*
dołączanie ukrytych plików, włączającdotglob
opcję powłoki.*.*
jest powszechne w systemie Windows (DOS) jako sposób na wyświetlenie listy wszystkich plików, ale w * nix będzie zawierać tylko pliki z kropką, więc nie ma to sensu w * nix. Zamiast tego używasz,*
aby wyświetlić listę wszystkich plików oprócz plików ukrytych oraz.*
listę plików ukrytych.Potrzebujesz
-d skip
dodanej opcji.Grep przeszukuje pliki. Możesz wyszukiwać rekurencyjnie, jak powiedziałeś, jeśli chcesz przeszukiwać pliki w katalogu.
Domyślnie grep odczytuje wszystkie pliki i wykrywa katalogi. Ponieważ domyślnie nie zdefiniowano, co zrobić z katalogami z tą
-d
opcją, daje to wynik błędu.Wyszukiwanie tylko w katalogu nadrzędnym byłoby `grep -d pomiń" string "./*
źródło
man grep
.-d skip
nie działa; jest w zasadzie taki sam jak-s
; zobacz także edycję. (c) Nie,grep -d skip "string" ./*
też nie działa.Dawni zegary prawdopodobnie zrobiliby to:
źródło
find . -type f -exec grep string {} +
?-maxdepth 1
.find . -type f -maxdepth 1 -exec grep string /dev/null {} +
-H
do grep.Przeprojektowanie - chcesz grepować pliki w jednym poziomie podkatalogu, ale nie powtarzać się we wszystkich podkatalogach?
Lub jeśli nie chcesz plików w bieżącym katalogu
Zauważ, że nie znajdzie katalogów zaczynających się od kropki.
powinien wykonać tę pracę.
Jest też
-maxdepth
i-mindepth
ograniczenie Parametry dostępne dlafind
komendy zbyt.źródło
grep forthis */*
wyszukiwałby plików zarówno w bieżącym katalogu, jak i w jednym katalogu?*/*
pasuje tylko do jednego ukośnika. Jeśli miałeś plik o nazwiea/b
w bieżącym katalogu, to `* / * pasowałby do niego.Oto przykład pomijania katalogów bez pomijania wszystkich błędów:
źródło