Je souhaite rechercher les lignes contenant lun des caractères suivants:
:
/
/
?
#
[
]
@
!
$
&
"
(
)
*
+
,
;
=
%
Réponse
grep "[]:/?#@\!\$&"()*+,;=%[]"
Dans une expression entre crochets, [...]
, très peu de caractères sont » special » (seulement un très petit sous-ensemble, comme ]
, -
et ^
, et les trois combinaisons [=
, [:
et [.
). Lorsque vous incluez ]
dans [...]
, le ]
doit venir en premier (éventuellement après un ^
). Jai choisi de mettre le ]
en premier et le [
en dernier pour la symétrie.
La seule autre chose à retenir est quune chaîne entre guillemets simples ne peut pas inclure de guillemets simples, nous utilisons donc des guillemets doubles autour de lexpression. Puisque nous utilisons une chaîne entre guillemets, le shell y fouille pour que les choses se développent. Pour cette raison, nous échappons au $
en tant que \$
ce qui donnera au shell un littéral $
en grep
, et nous échappons à !
en tant que \!
aussi car cest « une histoire expansion dans bash
(uniquement dans les shells bash
interactifs).
Souhaitez-vous inclure une barre oblique inverse dans le défini, vous devrez léchapper comme \\
afin que le shell donne une seule barre oblique inverse à grep
. De plus, si vous souhaitez inclure un backtick `
, il doit également être échappé sous la forme \`
car il lance une substitution de commande sinon.
La commande ci-dessus extrait toute ligne contenant au moins un des caractères de lexpression entre crochets.
Utiliser une chaîne entre guillemets simples au lieu dune chaîne entre guillemets doubles, ce qui permet de contourner la plupart des ennuis avec quels caractères le shell interprète:
grep "[]:/?#@!$&"""""()*+,;=%[]"
Ici, la seule chose à retenir, à part le placement du ]
, est quune chaîne entre guillemets simples ne peut pas inclure de guillemets simples, nous utilisons donc à la place une concaténation de trois chaînes:
-
"[]:/?#@!$&"
-
"""
-
"()*+,;=%[]"
Une autre approche consisterait à utiliser la classe de caractères POSIX [[:punct:]]
. Cela correspond à un seul caractère de lensemble !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~
, qui est un ensemble plus grand que ce qui « est donné dans la question (il contient en plus "-.<>^_`{|}~
), mais correspond à tous les » caractères de ponctuation » définis par POSIX.
LC_ALL=C grep "[[:punct:]]"
Commentaires
Réponse
Vous pouvez utiliser la classe de caractères [:punct:]
si vous ne craignez pas quil corresponde également à dautres signes de ponctuation et caractères spéciaux:
grep "[[:punct:]]" file
Commentaires
- Le
punct
classe de caractères (pas macro) correspond à!"#$%&'()*+,-./:;<=>?@[\]^_
{|} ~ `dans la locale C, qui est un jeu de caractères légèrement plus grand que ce que lutilisateur a, mais cela peut suffire.
Réponse
Vous pouvez utiliser lexpression régulière complète pour trouver caractères spéciaux entre crochets si vous recherchez un caractère spécial. Une excellente ressource pour pratiquer, apprendre et vérifier votre expression régulière est regex101.com .
Ceci utilise des expressions régulières Perl, qui peuvent être utilisées avec GNU grep avec loption -P
:
grep -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" ^^^
Notez que vous avez besoin de deux backsl cendres devant le signe dollar, car il a une signification particulière dans le shell, et la première barre oblique inverse lui échappera pour le shell. (Avec juste une barre oblique inverse à lavant, le shell supprimerait la barre oblique inverse, grep
verrait un signe dollar non échappé signifiant la fin de la ligne, et correspondrait à nimporte quelle ligne dentrée.)
Si votre terminal prend en charge les couleurs, ajoutez également des couleurs,
grep --color=auto -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])"
Voici lexplication de mon expression régulière de regex101.com
/(\:|\/|\?|\#|\@|\!|\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])/gm 1st Capturing Group (\:|\/|\?|\#|\@|\!|\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\]) \: matches the character : literally (case sensitive) \/ matches the character / literally (case sensitive) \? matches the character ? literally (case sensitive) \# matches the character # literally (case sensitive) \@ matches the character @ literally (case sensitive) \! matches the character ! literally (case sensitive) \$ matches the character $ literally (case sensitive) \& matches the character & literally (case sensitive) \" matches the character " literally (case sensitive) \( matches the character ( literally (case sensitive) \) matches the character ) literally (case sensitive) \* matches the character * literally (case sensitive) \+ matches the character + literally (case sensitive) \, matches the character , literally (case sensitive) \; matches the character ; literally (case sensitive) \= matches the character = literally (case sensitive) \% matches the character % literally (case sensitive) \[ matches the character [ literally (case sensitive) \] matches the character ] literally (case sensitive)
Commentaires
- Non, avec ERE standard, vous pouvez ‘ échapper à la fermeture
]
avec barre oblique inverse. la barre oblique inverse nest pas spéciale dans les expressions entre crochets. Pour avoir un]
dans une expression entre crochets, il doit être en premier:[]other]
, pas[ot\]her]
. Ce ‘ est différent des PCRE que regex101 décrivent par défaut. - Cela fonctionnerait avec
pcregrep
ou GNUgrep -P
, cependant. Et dans un sens, le comportement de Perl est plus simple: une barre oblique inverse rend toujours normal un caractère spécial. - Corrigé en -P, désolé, je mélange les -E et -P
$
là-dedans! Merci!bash: !\: event not found
.bash
! 🙂 Échappez aussi de!
… Nétant pas unbash
utilisateur que jai oublié. Je vais mettre à jour …"[\!]"
se développe en[\!]
même lorsque le développement de lhistorique est activé, il correspondrait à une barre oblique inverse. Vous ‘ avez besoin de guillemets simples ou en utilisant\!
outsi de guillemets.bash
,zsh
a également cette fonctionnalité ennuyeuse héritée de csh. dans csh,!
spécial à lintérieur de'...'
également, et aussi lorsquil nest pas interactif. Cependant danscsh
(contrairement à bash ou zsh), utiliser"\!"
fonctionnerait ici (la barre oblique inverse est supprimée).