Jeg vil søke etter linjene som inneholder et av følgende tegn:
:
/
/
?
#
[
]
@
!
$
&
"
(
)
*
+
,
;
=
%
Svar
grep "[]:/?#@\!\$&"()*+,;=%[]"
Innen et parentesuttrykk, [...]
, er svært få tegn » spesiell » (bare en veldig liten delmengde, som ]
, -
og ^
, og de tre kombinasjonene [=
, [:
og [.
). Når ]
inngår i [...]
, må ]
komme først (muligens etter en ^
). Jeg valgte å sette ]
først og [
sist for symmetri.
Den eneste andre tingen å huske er at en enkelt sitert streng ikke kan inkludere et enkelt sitat, så vi bruker doble anførselstegn rundt uttrykket. Siden vi bruker en dobbel sitert streng, vil skallet stikke rundt i det for at ting skal utvides. Av denne grunn unnslipper vi $
som \$
som vil få skallet til å gi en bokstavelig $
til grep
, og vi slipper !
som \!
også som det er en historie utvidelse i bash
(bare i interaktive bash
skjell skjønt).
Vil du ha et tilbakeslag i skråstrek sett, må du unnslippe det som \\
slik at skallet gir et enkelt tilbakeslag til grep
. Også hvis du vil inkludere et backtick `
, det må også unngås som \`
da det ellers starter en kommandosubstitusjon.
ovenfor ville trekke ut en linje som inneholdt minst ett av tegnene i parentesuttrykket.
Ved å bruke en enkelt sitert streng i stedet for en dobbel sitert streng, som omgir de fleste irritasjoner med hvilke tegn skallet tolker:
grep "[]:/?#@!$&"""""()*+,;=%[]"
Her er det eneste å huske, bortsett fra plasseringen av ]
, er at en enkelt sitert streng ikke kan inkludere et enkelt sitat, så i stedet bruker vi en sammenkobling av tre strenger:
-
"[]:/?#@!$&"
-
"""
-
"()*+,;=%[]"
En annen tilnærming ville være å bruke POSIX-tegnklassen [[:punct:]]
. Dette samsvarer med et enkelt tegn fra settet !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~
, som er et større sett enn det som er gitt i spørsmålet (det inneholder i tillegg "-.<>^_`{|}~
), men er alle » skilletegn » som POSIX definerer.
LC_ALL=C grep "[[:punct:]]"
Kommentarer
Svar
Du kan bruke [:punct:]
tegnklasse hvis du ikke husk at det også samsvarer med andre tegnsettingstegn og spesialtegn:
grep "[[:punct:]]" file
Kommentarer
-
punct
tegnklasse (ikke makro) samsvarer med!"#$%&'()*+,-./:;<=>?@[\]^_
{|} ~ `i C-lokalet, som er et lite stort sett med tegn enn hva brukeren har, men det kan være bra nok.
Svar
Du kan bruke full regex for å finne spesialtegn innenfor firkantede parenteser hvis du leter etter ett tegn som er et spesialtegn. En flott ressurs som trener, lærer og sjekker ditt regulære uttrykk er regex101.com .
Dette bruker Perl-regulære uttrykk, som kan brukes med GNU grep med -P
-alternativet:
grep -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" ^^^
Merk at du trenger to tilbakeslag aske foran dollartegnet, da det har en spesiell betydning i skallet, og det første tilbakeslaget vil unnslippe det for skallet. (Med bare ett skråstrek foran, ville skallet fjerne skråstrek, grep
ville se et unescaped dollartegn som betyr slutten av linjen, og matche enhver inngangslinje.)
Hvis terminalen din støtter farger, kaster du også farger,
grep --color=auto -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])"
Her er forklaringen på regexen min 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
- Nei, med standard ERE kan du ‘ for å unnslippe lukkingen
]
med tilbakeslag. tilbakeslag er ikke spesielt i brakettuttrykk. For å ha et]
inne i et parentesuttrykk, må det være først:[]other]
, ikke[ot\]her]
. At ‘ er forskjellig fra PCRE som regex101 beskriver som standard. - Det fungerer med
pcregrep
eller GNUgrep -P
, skjønt. Og på en måte er Perl-oppførselen mer enkel: en tilbakeslag gjør alltid en spesiell karakter normal. - Korrigert til -P, beklager det, jeg får blandet -E og -P sammen
$
der inne! Takk!bash: !\: event not found
.bash
! 🙂 Unnslipp!
også … Ikke å være enbash
bruker jeg glemte det. Jeg vil oppdatere …"[\!]"
utvides til[\!]
selv når utvidelse av historikk er aktivert, vil det stemme overens med tilbakeslag. Du ‘ d trenger enkle anførselstegn eller bruker\!
outsi de av anførselstegn.bash
,zsh
har også den irriterende funksjonen arvet fra csh. i csh,!
spesiell i'...'
også, og også når den ikke er interaktiv. Icsh
(i motsetning til bash eller zsh) vil bruk av"\!"
imidlertid fungere her (tilbakeslag skrives ut).