Voglio cercare le righe che contengono uno dei seguenti caratteri:
:
/
/
?
#
[
]
@
!
$
&
"
(
)
*
+
,
;
=
%
Risposta
grep "[]:/?#@\!\$&"()*+,;=%[]"
Allinterno di unespressione tra parentesi, [...]
, pochissimi caratteri sono ” speciale ” (solo un sottoinsieme molto piccolo, come ]
, -
e ^
e le tre combinazioni [=
, [:
e [.
). Quando includi ]
in [...]
, il ]
deve venire prima (possibilmente dopo un ^
). Ho scelto di inserire prima ]
e [
per simmetria.
Lunica altra cosa da ricordare è che una singola stringa tra virgolette non può includere una singola virgoletta, quindi utilizziamo le virgolette doppie attorno allespressione. Dato che usiamo una stringa con virgolette doppie, la shell si sposterà in essa per espandere le cose. Per questo motivo, usciamo da $
come \$
che farà sì che la shell fornisca un $
a grep
, e usciamo da !
come \!
come se fosse “cronologia espansione nelle bash
(solo nelle shell bash
interattive).
Si desidera includere una barra rovesciata nella impostato, dovresti eseguire lescape come \\
in modo che la shell fornisca una singola barra rovesciata a grep
. Inoltre, se desideri includere un backtick `
, anchesso deve essere sottoposto a escape come \`
poiché altrimenti avvia la sostituzione di un comando.
Il comando sopra estrarrebbe qualsiasi riga che contenga almeno uno dei caratteri nellespressione tra parentesi.
Lutilizzo di una singola stringa tra virgolette invece di una stringa tra virgolette doppie, che aggira la maggior parte dei fastidi con quali caratteri interpreta la shell:
grep "[]:/?#@!$&"""""()*+,;=%[]"
Qui, lunica cosa da ricordare, a parte il posizionamento del ]
, è che una singola stringa tra virgolette non può includere una singola virgoletta, quindi usiamo invece una concatenazione di tre stringhe:
-
"[]:/?#@!$&"
-
"""
-
"()*+,;=%[]"
Un altro approccio potrebbe essere quello di utilizzare la classe di caratteri POSIX [[:punct:]]
. Corrisponde a un singolo carattere del set !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~
, che è un set più grande di quello “s fornito nella domanda (contiene inoltre "-.<>^_`{|}~
), ma sono tutti i ” caratteri di punteggiatura ” definiti da POSIX.
LC_ALL=C grep "[[:punct:]]"
Commenti
Risposta
Puoi utilizzare la classe di caratteri [:punct:]
se non importa che corrisponda anche ad altri segni di punteggiatura e caratteri speciali:
grep "[[:punct:]]" file
Commenti
- Il
punct
classe di caratteri (non macro) corrisponde a!"#$%&'()*+,-./:;<=>?@[\]^_
{|} ~ `nella lingua C, che è un insieme di caratteri leggermente più grande di quello che ha lutente, ma potrebbe essere abbastanza buono.
Rispondi
Puoi usare lespressione regolare completa per trovare caratteri speciali allinterno di parentesi quadre se stai cercando un carattere che sia un carattere speciale. Una grande risorsa per esercitarti, apprendere e controllare la tua espressione regolare è regex101.com .
Questo utilizza espressioni regolari Perl, che possono essere usate con GNU grep con lopzione -P
:
grep -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" ^^^
Nota che hai bisogno di due backsl ceneri davanti al simbolo del dollaro, poiché ha un significato speciale nella shell, e la prima barra rovesciata sfuggirà per la shell. (Con una sola barra rovesciata davanti, la shell rimuove la barra rovesciata, grep
vedrebbe un segno di dollaro senza caratteri di escape che significa fine riga e corrisponderebbe a qualsiasi riga di input.) sup>
Se il tuo terminale supporta i colori, lancia anche i colori,
grep --color=auto -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])"
Ecco la spiegazione della mia regex da 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)
Commenti
- No, con ERE standard, non puoi ‘ sfuggire alla chiusura
]
con barra rovesciata. backslash non è speciale allinterno delle espressioni tra parentesi. Per avere un]
allinterno di unespressione di parentesi, deve essere prima:[]other]
, non[ot\]her]
. Questo ‘ è diverso dai PCRE descritti per impostazione predefinita da regex101. - Funzionerebbe con
pcregrep
o GNUgrep -P
, però. E in un certo senso, il comportamento di Perl è più semplice: una barra rovesciata rende sempre normale un carattere speciale. - Corretto in -P, mi dispiace, ho confuso -E e -P
$
lì! Grazie!bash: !\: event not found
.bash
! 🙂 Fuggi anche da!
… Non essere unbash
utente Me ne sono dimenticato. Aggiornerò …"[\!]"
si espande in[\!]
anche quando lespansione della cronologia è abilitata, corrisponderebbe alla barra rovesciata. ‘ hai bisogno di virgolette singole o utilizza\!
outsi de di virgolette.bash
,zsh
ha anche quella fastidiosa caratteristica ereditata da csh. in csh,!
speciale anche allinterno di'...'
e anche quando non interattivo. Tuttavia incsh
(contrariamente a bash o zsh), luso di"\!"
funzionerebbe qui (la barra rovesciata viene rimossa).