Kiedy używać pojedynczego cudzysłowu, podwójnego cudzysłowu w grep?

20

Podczas szukania prostego wzorca „witaj” w pliku działają wszystkie następujące formy grep:

  • plik grep hello 1
  • plik grep 'hello' 1
  • plik grep „hello” 1

Czy istnieje konkretny przypadek, w którym jedna z powyższych form działa, a inne nie. Czy robi to jakąkolwiek różnicę, jeśli używam jednego zamiast drugiego?


źródło

Odpowiedzi:

25

To zależy od twojej powłoki. Cytaty (oba rodzaje) mają przede wszystkim dotyczyć białych znaków. Na przykład:

grep hello world file1

szuka słowa „cześć” w plikach o nazwie „świat” i „plik1”, podczas gdy

grep "hello world" file1

wyszuka „witaj świecie” w pliku 1.

Wybór między pojedynczymi lub podwójnymi cudzysłowami jest ważny tylko wtedy, gdy szukany ciąg zawiera zmienne lub inne elementy, które mają zostać ocenione. W przypadku pojedynczych cudzysłowów ciąg jest brany dosłownie i nie następuje rozwinięcie. W przypadku podwójnych cudzysłowów zmienne są rozwijane. Na przykład (z powłoką pochodną Bourne'a, taką jak Bash lub ZSH):

VAR="serverfault"
grep '$VAR' file1
grep "$VAR" file1

Pierwszy grepszuka dosłownego ciągu „$ VAR1” w pliku1. Drugi rozwinie zmienną „$ VAR” i poszuka ciągu „serverfault” w pliku1.

James Sneeringer
źródło
Najważniejszą rzeczą do zapamiętania jest to, że w pierwotnym pytaniu grep faktycznie otrzymuje dokładnie te same argumenty za każdym razem.
MikeyB,
2
Uważaj tam. $jest końcem wiersza w wyrażeniu regularnym, więc $VAR1nigdy nie powinien właściwie pasować do niczego. Zdarza się, że działa na GNU grep, ale nadal nie liczyłbym na takie zachowanie. Musisz \$VAR1bezpiecznie dopasować dosłowny ciąg. (A ty potrzebować dodatkowych backslashy, czy to w cudzysłów.)
Steven Pritchard
7

James ma rację, ale aby dodać trochę więcej danych, myślę, że najlepszym sposobem myślenia o tym są argumenty polecenia: czy zamierzasz „cześć” i „świat” być dwoma argumentami, czy „cześć światem” być jednym argument.

Również podwójne cudzysłowy pozwalają interpretować coś więcej niż tylko zmienne. Dokładnie to, co zależy od powłoki, ale sprawdź ekspansję historii, nawias klamrowy i rozszerzenie nazwy pliku.

Ważne jest również, aby pamiętać, że istnieją przypadki, w których trzeba użyć obu typów cudzysłowów w jednym argumencie. Pamiętaj, że (domyślnie) argumenty są rozdzielane białymi spacjami, więc jeśli nie zostawisz miejsca, nadal podajesz ten sam argument.

Mechanizm pojedynczego cudzysłowu większości powłok nie dopuszcza żadnych znaków specjalnych, co oznacza, że ​​każde wystąpienie innego pojedynczego cudzysłowu, nawet jeśli wydaje się, że jest poprzedzone, kończy cytat. Dlatego nie jest możliwe przekazanie ciągu z pojedynczym cytatem w ciągu pojedynczego cudzysłowu i konieczne jest użycie podwójnych cudzysłowów. Może to być kłopotliwe, gdy chcesz przekazać argument zawierający pojedyncze cudzysłowy i coś, co można interpretować, ale nie chcesz. Na przykład, jeśli chcesz przekazać ciąg literalny „$ VAR” jest zmienną ”, musisz to zrobić w ten sposób:

"'"'$VAR'"' is a variable"

To właściwie połączenie trzech ciągów znaków bez cudzysłowu:

"'"
'$VAR'
"' is a variable"

lub, po usunięciu cytatów:

'
$VAR
' is a variable

W rzeczywistości w przypadku większości powłok można to zrobić w ten sposób:

"'\$VAR' is a variable"

gdzie ukośnik odwrotny („ \”) mówi powłoce, aby dosłownie zaakceptowała następujący znak i nie dokonywała na nim żadnego rozwinięcia.

Ale są pewne przypadki, w których kończy się to na łączeniu wielu strun, nie żebym w tej chwili mógł podać przykład.

wfaulk
źródło