Quand utiliser un guillemet simple, un guillemet double dans grep?

20

En essayant de rechercher un motif simple "bonjour" dans un fichier, toutes les formes suivantes de grep fonctionnent:

  • grep hello file1
  • grep 'bonjour' file1
  • grep "bonjour" file1

Existe-t-il un cas spécifique où l'un des formulaires ci-dessus fonctionne mais pas d'autres? Cela fait-il une différence si j'en utilise un à la place d'un autre?


la source

Réponses:

25

Cela dépend en fait de votre shell. Les citations (de toute nature) sont principalement destinées à traiter les espaces blancs. Par exemple, les éléments suivants:

grep hello world file1

recherchera le mot "bonjour" dans les fichiers appelés "world" et "file1", tandis que

grep "hello world" file1

recherchera "hello world" dans le fichier1.

Le choix entre des guillemets simples ou doubles n'est important que si la chaîne de recherche contient des variables ou d'autres éléments que vous attendez à évaluer. Avec des guillemets simples, la chaîne est prise littéralement et aucune expansion n'a lieu. Avec des guillemets doubles, les variables sont développées. Par exemple (avec un shell dérivé de Bourne tel que Bash ou ZSH):

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

Le premier greprecherchera la chaîne littérale "$ VAR1" dans le fichier1. Le second développera la variable "$ VAR" et recherchera la chaîne "serverfault" dans file1.

James Sneeringer
la source
L'essentiel à noter est que dans la question d'origine, grep reçoit en fait exactement les mêmes arguments à chaque fois.
MikeyB
2
Soyez prudent là-bas. $est en fin de ligne dans une expression régulière, $VAR1ne doit donc jamais correspondre à rien. Il se trouve que cela fonctionne sur GNU grep, mais je ne compterais toujours pas sur ce comportement. Vous devez \$VAR1faire correspondre la chaîne littérale en toute sécurité. (Et vous auriez besoin de barres obliques inverses supplémentaires si c'est entre guillemets.)
Steven Pritchard
7

James a raison, mais pour ajouter un peu plus de données, je pense que la meilleure façon d'y penser est comme arguments à la commande: avez-vous l'intention que "bonjour" et "monde" soient deux arguments ou "bonjour le monde" en soit un argument.

De plus, les guillemets doubles permettent d'interpréter plus que de simples variables. Exactement ce qui dépend de votre shell, mais vérifiez l'expansion de l'historique, l'expansion de l'accolade et l'expansion du nom de fichier.

Il est également important de noter qu'il existe des cas où vous devez utiliser les deux types de guillemets dans un seul argument. N'oubliez pas que (par défaut) les arguments sont délimités par des espaces, donc si vous ne laissez aucun espace, vous spécifiez toujours le même argument.

Le mécanisme de guillemet simple de la plupart des shells ne permet aucun caractère spécial, ce qui signifie que toute instance d'un autre guillemet simple, même s'il semble être échappé, termine la citation. Il est donc impossible de passer une chaîne avec un guillemet simple à l'intérieur d'une chaîne entre guillemets simples, et vous devez utiliser des guillemets doubles. Cela peut être pénible lorsque vous voulez passer un argument qui contient des guillemets simples et quelque chose qui serait interprété, mais vous ne voulez pas l'être. Par exemple, si vous vouliez passer la chaîne littérale "" $ VAR "est une variable", vous devez le faire de cette façon:

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

C'est en fait une concaténation de trois chaînes échappées par des guillemets:

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

ou, sans les guillemets:

'
$VAR
' is a variable

En fait, avec la plupart des coquilles, vous pouvez également le faire de cette façon:

"'\$VAR' is a variable"

où la barre oblique inverse (" \") indique au shell d'accepter littéralement le caractère suivant et de ne pas le développer.

Mais il y a des cas où vous finissez par devoir le faire de manière concaténée à plusieurs chaînes, pas que je puisse en fait trouver un exemple pour le moment.

wfaulk
la source