W dzisiejszych czasach ucząc się linux, znalazłem coś, co mnie zwierzyło :
$ cat abcd
line One
line Two
line Three
$ cat abcd | grep *
$ _ //nothing greped
$ cat abcd | grep ""
line One
line Two
line Three
$ cat abcd | grep "*"
$ _ //nothing greped
„_” to tylko kursor, nie pomyl się :)
kto by to wytłumaczył? Dzięki
_
? Na moim komputerze, to daje,_: command not found
.cat abcd | grep *
wydrukować?Odpowiedzi:
Glob
*
jest rozszerzany przez powłokę do alfabetycznej listy wszystkich (bez kropek) plików w bieżącym katalogu. Argumenty dogrep
to wyrażenie wyszukiwania i lista plików. Tak więcgrep *
kończy się na użyciu pierwszej nazwy pliku jako wyrażenia wyszukiwania. Szukasz nazwy pierwszego pliku (jako wyrażenia regularnego) w innych plikach.Grep przeszukuje standardowe dane wejściowe tylko wtedy, gdy nie podasz żadnych jawnych nazw plików. Widzieć:
Nawiasem mówiąc,
*
nie jest prawidłowym wyrażeniem regularnym. Jak odkryłeś, puste wyrażenie wyszukiwania pasuje do wszystkich linii wejściowych. Wyrażenie regularne pasujące do wszystkich niepustych linii wejściowych to.
; w wyrażeniu regularnym kropka jest metaznakiem, który pasuje do jednego znaku, dowolnego znaku z wyjątkiem znaku nowej linii. Gwiazda kleene jest operatorem przyrostka, który pozwala na zero lub więcej powtórzeń poprzedniego wyrażenia regularnego, więc często widzisz regex.*
dla „cokolwiek w ogóle”, ale w tym kontekście jest zbędny, ponieważ już nic nie dopasowujesz z pustym ciągiem wyszukiwania.Wreszcie jest uważany za złą formę
cat
pojedynczego pliku. Zamiast tegocat file | grep ""
zapisz proces i być może pogardę ,grep
czytając plik bezpośrednio;grep "" file
źródło
grep *
Ma zamiar zrobić „masek” przeciw ekspansji plików w bieżącym katalogu.Nie mogę dokładnie przewidzieć, co się stanie, ale z
*
pewnością będzie pasować doabcd
nazwy pliku. Więc możesz skończyć wyszukiwanie „abcd” wabcd
pliku. Lub może skończyć się wyszukiwaniem nazwy (leksykograficznie) pierwszego pliku w innych plikach.Jeśli bieżący katalog byłby pusty, skończyłbyś na wyszukiwaniu
*
. Ale to też nie zadziała, ponieważ pierwszy argument wiersza poleceń jest wyrażeniem regularnym, a „*” nie jest poprawnym wyrażeniem regularnym.Aby zapobiec globowaniu, napisz to:
... ale to nie ma sensu z podanego powyżej powodu.
Aby wyszukać dosłowny znak „*”:
źródło
echo *
Zanim
grep
zobaczy wiersz argumentu, ten argument jest analizowany przez powłokę. W przypadku powłoki*
symbol wieloznaczny oznacza „wszystkie pliki bez kropek w bieżącym katalogu”. Ponieważ powłoka obsługuje argument jako pierwszy, twoja linia zmienia się w:(zakładając, że te trzy pliki znajdują się w bieżącym katalogu). To właśnie
grep
widać z jej argumentów, ale nie jest to, czego chcesz.Zamiast tego możesz umieścić wzorzec
grep
w cudzysłowie, aby nie był przetwarzany przez powłokę:To lepiej, ale wciąż nie to, czego chcesz:
grep
używa wyrażeń regularnych, a nie symboli wieloznacznych w stylu powłoki. Gwiazdkagrep
oznacza, że „0..n powtórzeń poprzedniego znaku” - znak, którego nie określiłeś. Blisko, ale niezupełnie.Jeśli chcesz mieć „dowolny” wzorzec, szukasz „0..n powtórzeń dowolnego znaku”. Ten ostatni jest reprezentowany przez kropkę (
'.'
) w wyrażeniach regularnych:Tego właśnie szukałeś.
Edycja: Drugi przypadek można łatwiej wyjaśnić. Podczas
grep ""
gdy szukasz pustego łańcucha, który jest obecny jako podciąg w dowolnym łańcuchu.źródło
cat
jest bezużyteczny i wyrażenie regularne jest bezużyteczne. partmaps.org/era/unix/award.htmlcat
w tym przykładzie jest to ogólny stand-in „kiedy jestem grepping jakąś arbitralną standardowe wejście”. Odpowiedź jest łatwiejsza do zrozumienia, gdy nie zamienia abstrakcyjnego przykładu w coś zupełnie innego tylko po to, aby pokazać swoje umiejętności w zakresie unikania „niepotrzebnych” zastosowańcat
- ale pozostaje przy oryginalnym kodzie i pokazuje kilka zwrotów, które są faktycznie związane z rdzeniem pytania.chmod 0777 *
”, które czasem widzisz, ale w podejściu „po prostu napraw objawy” występuje pewna podobieństwo.$ cat abcd | grep ""
działa? Mam na myśli to, że jest to tylko pusty ciąg, od czego różni się (""
),"*"
a jednocześnie"*"
nic nie pasuje?Bash zawsze analizuje * jako symbole zastępcze symboli zastępczych dla pliku w katalogu. W twoim poleceniu bash przyjmuje to jako
więc pokazuje tylko puste dane wyjściowe, ponieważ nie jest to, czego szukasz
źródło
*
jest cytowany, nie będzie.