Comment puis-je rechercher une chaîne qui commence par un tiret / trait d'union?

347

Je veux grep pour la chaîne qui commence par un tiret / trait d'union, comme -Xdans un fichier, mais cela confond cela comme argument de ligne de commande.

J'ai essayé:

grep "-X"
grep \-X
grep '-X'
Mike
la source

Réponses:

465

Utilisation:

grep -- -X

En relation: Que signifie un double tiret nu? (merci à nutty à propos de natty ).

newacct
la source
57
pour ceux d'entre nous qui se demandent à ce stade ce que --signifie ou fait: unix.stackexchange.com/questions/11376/…
about natty
2
Fonctionne également avec Silver Searcher (ag).
Zev Eisenberg
Si vous souhaitez utiliser des variables ayant des espaces, vous devez utiliser quelque chose comme ceci:ARGS="-a -b -c" grep -- "$ARGS"
zapstar
2
@zapstar Ou tout simplement, grep -- "--name awesome".
Brett Widmeier
@BrettWidmeier, oui, je n'aurais pas dû utiliser la variable, cela déroute les gens.
zapstar
57

Le tiret est un caractère spécial dans Bash, comme indiqué sur http://tldp.org/LDP/abs/html/special-chars.html#DASHREF . Donc, échapper à cela une fois vous permet de dépasser Bash, mais Grep a toujours sa propre signification pour les tirets (en fournissant des options).

Vous devez donc vraiment y échapper deux fois (si vous préférez ne pas utiliser les autres réponses mentionnées). Les éléments suivants fonctionneront / devraient fonctionner

grep \\-X
grep '\-X'
grep "\-X"

Une façon d'essayer comment Bash passe des arguments à un script / programme est de créer un script .sh qui fait écho à tous les arguments. J'utilise un script appelé echo-args.sh pour jouer de temps en temps, tout ce qu'il contient est:

echo $*

Je l'invoque comme:

bash echo-args.sh \-X
bash echo-args.sh \\-X
bash echo-args.sh "\-X"

Vous avez eu l'idée.

Chad Gorshing
la source
1
Je ne pense pas - est un personnage spécial dans Bash malgré ce que dit le guide ABS. Bash ne traite pas les arguments commençant par - différemment des autres. La commande ou intégrée que Bash appelle par la suite gérera les arguments commençant par un tiret comme bon lui semble. La plupart des commandes intégrées Bash et Linux et GNU sont gérées - comme terminateur d'option. Utilisez 'set -x' pour voir les commandes et les arguments que Bash utilise avant leur exécution, mais après que Bash a développé les échappements, les globes et les accolades. Grep est un exemple déroutant car il gère lui-même les échappements antislash.
Noah Spurrier
25

grep -e -X fera l'affaire.

Thomas
la source
1
mon grep n'a pas -e, très bizarre
Mike
14
Solaris pour les perdants
Mike
2
Disponible sur solaris à partir de / usr / xpg4 / bin / grep, btw. Beaucoup d'utilitaires plus complets dans ce répertoire.
pra
Cela a fonctionné sous MinGW ( MinGW ne prend pas en charge -P(mais c'est une autre histoire et ne s'applique pas ici)).
Peter Mortensen
20
grep -- -X
grep \\-X
grep '\-X'
grep "\-X"
grep -e -X
grep [-]X
John Henry
la source
7

Je n'ai pas accès à une machine Solaris, mais grep "\-X"fonctionne pour moi sur Linux.

ezpz
la source
5

La bonne façon serait d'utiliser "-" pour arrêter le traitement des arguments, comme déjà mentionné. Cela est dû à l'utilisation de getopt_long (fonction C GNU de getopt.h) dans la source de l'outil.

C'est pourquoi vous remarquez le même phénomène sur d'autres outils de ligne de commande; puisque la plupart d'entre eux sont des outils GNU et utilisent cet appel, ils présentent le même comportement.

En guise de remarque - getopt_long est ce qui nous donne le bon choix entre -rlo et --really_long_option et la combinaison d'arguments dans l'interpréteur.

fmmarques
la source
3

Si vous utilisez un autre utilitaire qui transmet un seul argument à grep, vous pouvez utiliser:

'[-]X'
Colin vH
la source
2

vous pouvez utiliser nawk

$ nawk '/-X/{print}' file
ghostdog74
la source
-1
ls -l | grep "^-"

J'espère que celui-ci servira votre objectif.

XINU
la source
2
Cette expression n'attrape que les lignes commençant par un tiret. Il ne répond pas à la question initiale. Il veut rechercher une chaîne commençant par un tiret, mais les lignes qui contiennent cette chaîne n'ont pas nécessairement commencé par un tiret.Dans la question initiale, la chaîne commençant par un tiret peut être n'importe où sur la ligne.
Laurent Simon
-1

grep "^ -X" fichier

Il va grep et sélectionner toutes les lignes du fichier. ^ dans le grep "^" indique une ligne commençant par

sasank
la source
1
Il y a déjà une réponse qui suggère que stackoverflow.com/a/27440348/441757 (publié il y a plus d'un an)
sideshowbarker
L'OP recherche des chaînes commençant par -, pas des lignes.
codeforester