Quiero buscar las líneas que contienen cualquiera de los siguientes caracteres:
:
/
/
?
#
[
]
@
!
$
&
"
(
)
*
+
,
;
=
%
Responder
grep "[]:/?#@\!\$&"()*+,;=%[]"
Dentro de una expresión entre corchetes, [...]
, muy pocos caracteres son » especial » (solo un subconjunto muy pequeño, como ]
, -
y ^
, y las tres combinaciones [=
, [:
y [.
). Al incluir ]
en [...]
, el ]
debe ir primero (posiblemente después de un ^
). Opté por poner el ]
primero y el [
último para la simetría.
Lo único que hay que recordar es que una sola cadena entre comillas no puede incluir una sola comilla, por lo que usamos comillas dobles alrededor de la expresión. Como usamos una cadena entre comillas dobles, el shell buscará en ella para que las cosas se expandan. Por esta razón, escapamos de $
como \$
que hará que el shell dé un $
a grep
, y escapamos de !
como \!
también como «un historial expansión en bash
(solo en shells bash
interactivos).
¿Le gustaría incluir una barra invertida en el establecido, tendría que escaparlo como \\
para que el shell muestre una sola barra invertida a grep
. Además, si desea incluir una comilla invertida `
, también debe escaparse como \`
ya que de lo contrario inicia una sustitución de comando.
El comando anterior extraería cualquier línea que contuviera al menos uno de los caracteres en la expresión entre corchetes.
Usar una sola cadena entre comillas en lugar de una cadena entre comillas dobles, lo que evita la mayoría de las molestias con qué caracteres interpreta el shell:
grep "[]:/?#@!$&"""""()*+,;=%[]"
Aquí, lo único que hay que recordar, aparte de la ubicación del ]
, es que una sola cadena entre comillas no puede incluir una sola comilla, por lo que en su lugar usamos una concatenación de tres cadenas:
-
"[]:/?#@!$&"
-
"""
-
"()*+,;=%[]"
Otro enfoque sería utilizar la clase de caracteres POSIX [[:punct:]]
. Esto coincide con un solo carácter del conjunto !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~
, que es un conjunto más grande que lo que «se da en la pregunta (además contiene "-.<>^_`{|}~
), pero son todos los » caracteres de puntuación » que define POSIX.
LC_ALL=C grep "[[:punct:]]"
Comentarios
Responder
Puede usar la clase de caracteres [:punct:]
si No importa que también coincida con otros signos de puntuación y caracteres especiales:
grep "[[:punct:]]" file
Comentarios
- El
punct
la clase de caracteres (no macro) coincide con!"#$%&'()*+,-./:;<=>?@[\]^_
{|} ~ `en la configuración regional C, que es un conjunto de caracteres ligeramente mayor que lo que tiene el usuario, pero puede ser lo suficientemente bueno.
Responder
Puede usar expresiones regulares completas para encontrar caracteres especiales dentro de corchetes si está buscando un carácter que sea un carácter especial. Un gran recurso para practicar, aprender y verificar su expresión regular es regex101.com .
Esto usa expresiones regulares de Perl, que se pueden usar con GNU grep con la opción -P
:
grep -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" ^^^
Tenga en cuenta que necesita dos backsl cenizas delante del signo de dólar, ya que tiene un significado especial en el caparazón, y la primera barra invertida se escapará para el caparazón. (Con solo una barra invertida al frente, el shell eliminaría la barra invertida, grep
vería un signo de dólar sin escape que significa el final de la línea y coincidiría con cualquier línea de entrada).
Si su terminal admite colores, coloque colores también,
grep --color=auto -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])"
Aquí está la explicación de mi expresión regular 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)
Comentarios
- No, con ERE estándar, no puede ‘ escapar del cierre
]
con barra invertida. La barra invertida no es una expresión especial entre corchetes. Para tener un]
dentro de una expresión entre corchetes, debe ser primero:[]other]
, no[ot\]her]
. Eso ‘ es diferente de los PCRE que regex101 describen por defecto. - Funcionaría con
pcregrep
o GNUgrep -P
, sin embargo. Y, en cierto sentido, el comportamiento de Perl es más sencillo: una barra invertida siempre hace que un carácter especial sea normal. - Corregido a -P, lo siento, me confunden -E y -P
$
¡Gracias!bash: !\: event not found
.bash
! 🙂 Escapa también de!
… No ser unbash
usuario Lo olvidé. Actualizaré …"[\!]"
se expande a[\!]
incluso cuando la expansión del historial está habilitada, coincidiría en la barra invertida. ‘ d necesita comillas simples o usar\!
de comillas.bash
,zsh
también tiene esa característica molesta heredada de csh. en csh,!
especial dentro de'...'
también, y también cuando no es interactivo. Sin embargo, encsh
(al contrario de bash o zsh), el uso de"\!"
funcionaría aquí (la barra invertida se elimina).