Jeg vil søge efter de linjer, der indeholder et af følgende tegn:
:
/
/
?
#
[
]
@
!
$
&
"
(
)
*
+
,
;
=
%
Svar
grep "[]:/?#@\!\$&"()*+,;=%[]"
Inden for et parentes udtryk, [...]
, er meget få tegn ” special ” (kun en meget lille delmængde, som ]
, -
og ^
, og de tre kombinationer [=
, [:
og [.
). Når ]
medtages i [...]
, skal ]
komme først (muligvis efter en ^
). Jeg valgte at sætte ]
først og [
sidst til symmetri.
Den eneste anden ting at huske er at en enkelt citeret streng ikke kan inkludere et enkelt citat, så vi bruger dobbelt anførselstegn omkring udtrykket. Da vi bruger en dobbelt citeret streng, vil skallen stikke rundt i den for at ting kan udvides. Af denne grund undslipper vi $
som \$
som får skallen til at give en bogstavelig $
til grep
, og vi undslipper !
som \!
også som det er en historie udvidelse i bash
(kun i interaktive bash
skaller dog).
Vil du medtage et tilbageslag i sæt, bliver du nødt til at undslippe det som \\
, så skallen giver et enkelt tilbageslag til grep
. Hvis du også vil medtage et backtick `
, det skal også undslippes som \`
da det ellers starter en kommandosubstitution.
Kommandoen ovenfor ville udtrække en hvilken som helst linje, der indeholdt mindst et af tegnene i parentesudtrykket.
Brug af en enkelt citeret streng i stedet for en dobbelt citeret streng, som kommer omkring de fleste irritationer med hvilke tegn skallen fortolker:
grep "[]:/?#@!$&"""""()*+,;=%[]"
Her er den eneste ting at huske, bortset fra placeringen af ]
, er, at en enkelt citeret streng ikke kan inkludere et enkelt citat, så i stedet bruger vi en sammenkædning af tre strenge:
-
"[]:/?#@!$&"
-
"""
-
"()*+,;=%[]"
En anden tilgang ville være at bruge POSIX-tegnklassen [[:punct:]]
. Dette matcher et enkelt tegn fra sættet !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~
, som er et større sæt end hvad der er givet i spørgsmålet (det indeholder desuden "-.<>^_`{|}~
), men er alle ” tegnsætningstegn “, som POSIX definerer.
LC_ALL=C grep "[[:punct:]]"
Kommentarer
Svar
Du kan bruge [:punct:]
tegnklasse, hvis du husk ikke, at det også matcher andre tegnsætningstegn og specialtegn:
grep "[[:punct:]]" file
Kommentarer
-
punct
tegnklasse (ikke makro) matcher!"#$%&'()*+,-./:;<=>?@[\]^_
{|} ~ `i C-lokalet, hvilket er et lidt større sæt tegn end hvad brugeren har, men det kan være godt nok.
Svar
Du kan bruge fuld regex til at finde specialtegn inden for firkantede parenteser, hvis du leder efter et tegn, der er et specialtegn. En stor ressource, der praktiserer, lærer og kontrollerer dit regulære udtryk er regex101.com .
Dette bruger Perl-regulære udtryk, som kan bruges med GNU grep med -P
-indstillingen:
grep -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" ^^^
Bemærk, at du har brug for to backsl aske foran dollartegnet, da det har en særlig betydning i skallen, og det første tilbageslag vil undslippe det for skallen. (Med kun en tilbageslag skrå foran, fjernede skallen backslash, grep
ville se et unescaped dollartegn, der betyder slutningen af linjen, og matche enhver inputlinje.)
Hvis din terminal understøtter farver, skal du også kaste farver på,
grep --color=auto -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])"
Her er forklaringen på min regex fra 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)
Kommentarer
- Nej, med standard ERE kan du ‘ for at undslippe lukningen
]
med tilbageslag. tilbageslag er ikke specielt inden for parentesudtryk. For at have et]
inde i et parentesudtryk skal det være først:[]other]
, ikke[ot\]her]
. At ‘ er forskellig fra PCREer, som regex101 som standard beskriver. - Det fungerer med
pcregrep
eller GNUgrep -P
. Og på en måde er Perl-opførelsen mere ligetil: en tilbageslag gør altid en speciel karakter normal. - Korrigeret til -P, undskyld det, jeg får -E og -P blandet sammen
$
derinde! Tak!bash: !\: event not found
.bash
! 🙂 Undslip!
også … Ikke enbash
bruger, jeg har glemt det. Jeg opdaterer …"[\!]"
udvides til[\!]
selv når historikudvidelse er aktiveret, ville det matche i tilbageslag. Du ‘ d har brug for enkelt anførselstegn eller bruger\!
outsi de af citater.bash
,zsh
har også den irriterende funktion nedarvet fra csh. i csh,!
specielt inden i'...'
også, og også når det ikke er interaktivt. Icsh
(i modsætning til bash eller zsh) vil brug af"\!"
dog fungere her (tilbageslag skrånes fjernet).