Porównanie dwóch komend wyszukiwania

12

Niedawno otrzymałem ten findlinijka, ale nie jestem w stanie wyjaśnić, skąd bierze się różnica między dwoma poniżej:

Przykład 1

[root@centos share]# find . -exec grep -i "madis" {} /dev/null \;

./names:Madison Randy:300:Product Development

Przykład 2

[root@centos share]# find . -exec grep -i "madis" {} \;

Madison Randy:300:Product Development

Jak widać, w pierwszym znajduje się konkretny plik, z którego pochodzi ten ciąg i jak dotąd naprawdę nie jestem w stanie dowiedzieć się, dlaczego tak się dzieje.

VVelev
źródło

Odpowiedzi:

17

Mówisz grepowi, aby przeszukał 2 lokalizacje. grep pokazuje pełną lokalizację tylko w przypadku wyszukiwania wielu lokalizacji.

Na przykład

touch /tmp/herp /tmp/derp
cd /tmp
echo "foo" > herp
echo "foo" > derp

Zauważ, że jeśli szukam tylko 1 pliku, grep pomija nazwę pliku

grep -i "foo" /tmp/herp
foo

Ale jeśli podam wiele lokalizacji wyszukiwania, grep mówi, gdzie znalazł każde dopasowanie

grep -i "foo" herp derp
/tmp/derp:foo
/tmp/herp:foo

Dodanie /dev/nullpolega na oszukiwaniu grep w celu wydrukowania pełnej ścieżki, podając 2 argumenty.

spuder
źródło
1
+1, ale zapomniałeś wspomnieć o „oczywistym”: „Powodem dodania pliku jest /dev/nullupewnienie się, że to, co jest grep-ed, nie zostanie znalezione w (pustym) /dev/nullpliku, więc wyświetlane są tylko poprawne lokalizacje”
Olivier Dulac
Ale także, przeszukując /dev/null, nie marnujesz czasu na przeszukiwanie niepustego pliku fikcyjnego. I wreszcie cel poszukiwań /dev/nulljest oczywisty dla osób zaznajomionych z tym idiomem.
Alexis
5

man grep:

-H, - z nazwą pliku

Wydrukuj nazwę pliku dla każdego dopasowania. Jest to ustawienie domyślne, gdy istnieje więcej niż jeden plik do przeszukania.

Różnica wynika z wywołania grep z jednym lub dwoma argumentami pliku w obu przypadkach. Zamiast dodawać /dev/nullmożesz zadzwonić grepz argumentem -H. Być może /dev/nullzachowanie jest szerzej obsługiwane.

Hauke ​​Laging
źródło
3
grep -Hnie jest przenośny - /dev/nullsztuczka działa bez GNU grep.
Chris Down
4

Pierwszy przykład jest równoważny z uruchomieniem grep na dwóch plikach dla każdego pliku znalezionego w wyniku findwyrażenia. Na przykład, jeśli findznajdzie trzy pliki a.txt, b.txta c.txtnastępnie grepuruchomi się jako

grep -i "madis" a.txt /dev/null
grep -i "madis" b.txt /dev/null 
grep -i "madis" c.txt /dev/null

Do którego grepzostanie wyświetlona nazwa pliku, do którego pasuje wyjście. Ponieważ nic nie będzie pasować do / dev / null, gwarantuje się, że nazwa pierwszego pliku zostanie wydrukowana, jeśli będzie pasować.

Natomiast drugi przykład jest równoważny z

grep -i "madis" a.txt
grep -i "madis" b.txt 
grep -i "madis" c.txt 

W takim przypadku nazwa pliku nie zostanie wydrukowana dla dopasowań, ponieważ istnieje tylko jeden argument.

mkc
źródło