2012-11-22 16 views
8

Chciałbym znać różnicę między poniżej 2 poleceń, Rozumiem, że 2) powinny być używane, ale chcę znać dokładną sekwencję, która dzieje się w 1) i 2) załóżmy, że nazwa pliku ma 200 znaki w nimróżnica między grep Vs cat i grep

1) cat nazwa pliku | grepa REGEX

2) grep regex fileName

Odpowiedz

0

są funkcjonalnie równoważne, jednak powłoka widelec dwa procesy cat filename | grep regex i połączyć je z rurą.

4

Pierwszy:

cat filename | grep regex 

Zwykle kot otwiera plik i wyświetla jego zawartość linia po linii na standardowe wyjście. Ale tutaj wyprowadza swoją treść do potoku "|". Po tym grep odczytuje z potoku (pobiera potok jako stdin), a następnie, jeśli pasuje, regex drukuje linię na stdout. Ale tutaj jest szczegółowo otwierany grep w nowym procesie powłoki, więc rura przekazuje dane wejściowe jako wyjście do nowego procesu powłoki.

drugie jeden:

grep regex filename 

Tutaj grep czyta bezpośrednio z pliku (powyżej było czytanie z rury) i pasuje do wyrażenia regularnego, jeżeli linia dopasowane drukuje na standardowe wyjście.

+0

+1: pedant (np ja) mogą twierdzić, że 'cat' zawsze pisze na standardowe wyjście, ale w kontekst potoku, jego standardowym wyjściem jest koniec zapisu rury. Podobnie, gdy 'grep' jest wywoływany bez argumentów nazw plików lub gdy przetwarza argument nazwy pliku' -', to odczyta jego standardowe wejście, które w tym przypadku jest odczytanym końcem potoku. Zauważ, że 'pipe' lub' | 'nie jest poleceniem; nie jest całkiem jasne, czy rozpoznajesz, że "tak potok przekazuje dane wejściowe jako wynik do nowego procesu powłoki". –

14

Funkcjonalnie (pod względem wydajności), te dwa są takie same. Pierwszy z nich faktycznie tworzy oddzielny proces, który po prostu wysyła zawartość pliku na standardowe wyjście, które pojawia się na standardowym wejściu grep, ponieważ powłoka połączyła je z rurą.

W tym sensie grep regex <filename jest również równoważny, ale z jednym procesem mniej.

Jeżeli zaczniesz widzieć różnica jest w wariantach, gdy dodatkowa informacja (nazwy plików) jest wykorzystywane przez grep, takie jak z:

grep -n regex filename1 filename2 

Różnica między tym a:

cat filename1 filename2 | grep -n regex 

jest to, że były wie o poszczególnych plikach natomiast ostatni widzi go jako jeden pliku (bez nazwy).

Choć dawny może dać Ci:

filename1:7:line with regex in 10-line file 
filename2:2:another regex line 

ten ostatni będzie więcej takich jak:

7:line with regex in 10-line file 
12:another regex line 

Innym wykonywalny, który działa odmiennie, jeśli zna nazw plików jest wc The programy liczników słów:

$ cat qq.in 
1 
2 
3 

$ wc -l qq.in   # knows file so prints it 
3 qq.in 

$ cat qq.in | wc -l  # does not know file 
3 

$ wc -l <qq.in   # also does not know file 
3 
1

Jeśli chcesz sprawdzić aktualną roznicy czasu wykonania, najpierw utworzyć plik z 100000 wierszy:

[email protected] ~ $ for i in $(seq 1 100000); do echo line${1} >> test_f; done 
[email protected] ~ $ wc -l test_f 
100000 test_f 

teraz zmierzyć:

[email protected] ~ $ time grep line test_f 
#... 
real 0m1.320s 
user 0m0.101s 
sys  0m0.122s 

[email protected] ~ $ time cat test_f | grep line 
#... 
real 0m1.288s 
user 0m0.132s 
sys  0m0.108s 

Jak widzimy, diffrence nie jest zbyt duży. ..

+0

Czy drugie polecenie 'time' wydłuża czas trwania' cat' lub całego potoku? –

+3

Ile czasu zaobserwowałeś z powodu pominiętych wyników zapisanych na ekranie? Próbowałem z wyjściem 'grep' przekierowanym do'/dev/null' i otrzymałem czasy w zakresie 10-50 ms, a nie 1 sekundę. Teraz moja maszyna nie jest ciasna, ale 20 razy szybsza od twojej wydaje się mało prawdopodobna (nawet przy założeniu, że plik prawdopodobnie jest głównie w pamięci, a nie na dysku). Bardzo trudno jest przeprowadzić dobry test porównawczy. Obawiam się, że mierzysz, to czas potrzebny na napisanie 100 000 linii do twojego terminalu, zamiast surowego wykonania 'grep' kontra' cat | grep'. –

+0

Możesz mieć rację, nie wziąłem tego pod uwagę. – dstronczak

0

W rzeczywistości, chociaż wyniki są takie same;

-$cat filename | grep regex 

To polecenie szuka zawartości pliku "filename", a następnie pobiera wyrażenie regularne; podczas

-$grep regex filename 

To polecenie wyszukuje bezpośrednio za treść nazwie regex w pliku „nazwa pliku”