J'ai un fichier qui a "alors" et "là".
je peux
$ grep "then " x.x
x and then some
x and then some
x and then some
x and then some
et je peux
$ grep "there " x.x
If there is no blob none some will be created
Comment puis-je rechercher les deux en une seule opération? j'ai essayé
$ grep (then|there) x.x
-bash: erreur de syntaxe près d'un jeton inattendu `('
et
grep "(then|there)" x.x
durrantm.../code
# (Nothing)
grep
regular-expression
Michael Durrant
la source
la source
Réponses:
Vous devez mettre l'expression entre guillemets. L'erreur que vous recevez est le résultat de l'interprétation
(
que bash fait du caractère spécial.En outre, vous devez indiquer à grep d'utiliser des expressions régulières étendues.
Sans expressions régulières étendues, vous devez échapper à la
|
,(
et)
. Notez que nous utilisons des guillemets simples ici. Bash traite spécialement les barres obliques inverses entre guillemets doubles.Le regroupement n'est pas nécessaire dans ce cas.
Ce serait nécessaire pour quelque chose comme ça:
la source
grep $'then\nthere'
etgrep -e then -e there
. Notez que ce\|
n'est pas la norme dans les BRE. Le reste est. Bash traite antislashs spécialement dans des guillemets doubles seulement avant"
,$
,\
,`
et retour à la ligne.x.x
?Juste un petit ajout, la plupart des versions ont une commande appelée egrep qui est juste grep avec -E. Personnellement, j'aime beaucoup mieux taper
Que d'utiliser grep -E
la source
Les éléments documentés sous REGULAR EXPRESSIONS dans la page de manuel (ou du moins, my) s’appliquent réellement aux expressions rationnelles étendues ;
Mais grep ne les utilise pas par défaut - vous avez besoin du
-E
commutateur:Parce que (de la page de man à nouveau):
Donc vous pouvez aussi utiliser:
Puisque les parenthèses sont superflues dans ce cas.
la source
La simplicité élégante de Bash semble se perdre dans son énorme page de manuel.
En plus des excellentes solutions ci-dessus, j'ai pensé essayer de vous donner une triche sur la façon dont bash analyse et interprète les déclarations . Ensuite, en utilisant cette feuille de route, je vais analyser les exemples présentés par le questionneur pour vous aider à mieux comprendre pourquoi ils ne fonctionnent pas comme prévu.
Remarque: les lignes de script shell sont utilisées directement. Les lignes d'entrée typées sont d'abord enrichies en historique.
Chaque ligne de bash est d'abord symbolisée , ou autrement dit découpée en ce que l'on appelle des jetons . (La création de jetons a lieu avant toutes les autres extensions, notamment l'accolade, le tilde, le paramètre, la commande, l'arithmétique, le processus, le fractionnement des mots et le développement du nom de fichier.)
Un jeton signifie ici une partie de la ligne d'entrée séparée (délimitée) par l'un de ces méta-caractères spéciaux:
Bash utilise beaucoup d'autres caractères spéciaux, mais seuls ces 10 produisent les jetons initiaux.
Cependant, étant donné que ces méta-caractères doivent parfois aussi être utilisés dans un jeton, il doit exister un moyen de supprimer leur signification particulière. Ceci s'appelle s'échapper. L'échappement se fait soit en citant une chaîne d'un ou de plusieurs caractères (c.-à
'xx..'
- d ."xx.."
), Soit en préfixant un caractère individuel avec une barre oblique inversée (c.-à-d\x
.). (C'est un peu plus compliqué que cela parce que les guillemets doivent également être cités et que les guillemets doubles ne citent pas tout, mais cette simplification conviendra pour le moment.)Ne confondez pas bash quotes avec l'idée de citer une chaîne de texte, comme dans d'autres langues. Ce qui est entre guillemets dans bash ne correspond pas à des chaînes, mais plutôt à des sections de la ligne d'entrée dans lesquelles des méta-caractères ont été échappés afin de ne pas délimiter les jetons.
Notez qu'il y a une différence importante entre
'
, et"
, mais c'est pour un autre jour.Les méta-caractères non échappés restants deviennent alors des séparateurs de jetons.
Par exemple,
Dans le premier exemple, il y a deux jetons produits par un délimiteur d'espace:
echo
etxyz
.De même dans le 2ème exemple.
Dans le troisième exemple est le point - virgule échappé, donc il y a 4 jetons produits par un séparateur d'espace,
echo
,x;
,echo
ety
. Le premier jeton est ensuite exécuté en tant que commande et prend les trois prochains jetons en entrée. Notez que le 2èmeecho
n'est pas exécuté.La chose importante à retenir est que les premiers regards pour les personnages bash Évasion (
'
,"
et\
), et cherche ensuite délimiteurs méta-caractères unescaped, dans cet ordre.Sinon, ces 10 caractères spéciaux servent de
token
délimiteurs. Certains d'entre eux ont également une signification supplémentaire, mais ils sont avant tout des délimiteurs symboliques.Ce que grep attend
Dans l'exemple ci - dessus grep a besoin de ces jetons,
grep
,string
,filename
.Le premier essai de la question était:
Dans ce cas
(
,)
et|
sont des caractères meta unescaped et ainsi servent à diviser l'entrée en ces jetons:grep
,(
,then
,|
,there
,)
etx.x
. grep veut voirgrep
,then|there
etx.x
.Le deuxième essai de la question était:
Ce tokenizes dans
grep
,(then|there)
,x.x
. Vous pouvez voir cela si vous remplacez grep par echo:la source