Jag vill söka efter raderna som innehåller något av följande tecken:

: / / ? # [ ] @ ! $ & " ( ) * + , ; = %

Svar

grep "[]:/?#@\!\$&"()*+,;=%[]" 

Inom ett parentesuttryck, [...], är mycket få tecken ” special ” (bara en mycket liten delmängd, som ], - och ^, och de tre kombinationerna [=, [: och [.). När ] ingår i [...] måste ] komma först (eventuellt efter en ^). Jag valde att sätta ] först och [ för symmetri.

Det enda andra att komma ihåg är att en enda citerad sträng inte kan innehålla ett enda citat, så vi använder dubbla citat runt uttrycket. Eftersom vi använder en dubbel citerad sträng kommer skalet att peka runt i det för att saker ska kunna expandera. Av denna anledning flyr vi från $ som \$ vilket gör att skalet ger en bokstavlig $ till grep, och vi flyr ! som \! också eftersom det är en historia expansion i bash (endast i interaktiva bash skal men.)

Vill du inkludera ett bakåt snedstreck i inställt, måste du fly från det som \\ så att skalet ger ett enda snedstreck till grep. Om du vill inkludera ett backtick `, det måste också undvikas som \` eftersom det annars startar ett kommandosubstitution.

ovan skulle extrahera alla rader som innehöll minst ett av tecknen i parentesuttrycket.


Använda en enda citerad sträng i stället för en dubbel citerad sträng, som får runt de flesta irritationerna med vilka tecken skalet tolkar:

grep "[]:/?#@!$&"""""()*+,;=%[]" 

Här är det enda att komma ihåg, förutom placeringen av ], är att en enda citerad sträng inte kan inkludera ett enda citat, så istället använder vi en sammankoppling av tre strängar:

  1. "[]:/?#@!$&"
  2. """
  3. "()*+,;=%[]"

Ett annat tillvägagångssätt skulle vara att använda POSIX-teckenklassen [[:punct:]]. Detta matchar ett enstaka tecken från uppsättningen !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~, vilket är en större uppsättning än vad som ges i frågan (den innehåller dessutom "-.<>^_`{|}~), men är alla ” skiljetecken ” som POSIX definierar.

LC_ALL=C grep "[[:punct:]]" 

Kommentarer

  • @ilkkachu Jag upptäckte inte ’ t $ där inne! Tack!
  • När jag försöker utföra kommandot får jag det här felet bash: !\: event not found.
  • @ user9371654 Darn bash! 🙂 Undvik ! också … Är inte en bash användare Jag glömde bort det. Jag kommer att uppdatera …
  • "[\!]" expanderar till [\!] även när historikutvidgning är aktiverad, så skulle det matcha i motsatt snedstreck. Du ’ d behöver enstaka citat eller använder \! outsi de av citat.
  • Observera att det ’ inte bara bash, zsh har också den irriterande funktionen ärvt från csh. i csh, ! special inuti '...', och även när det inte är interaktivt. Men i csh (i motsats till bash eller zsh) skulle användning av "\!" fungera här (bakåtvänd snedstreck tas bort).

Svar

Du kan använda [:punct:] teckenklass om du tänk inte på att det också matchar andra skiljetecken och specialtecken:

grep "[[:punct:]]" file 

Kommentarer

  • punct teckenklass (inte makro) matchar !"#$%&'()*+,-./:;<=>?@[\]^_ {|} ~ `i C-området, vilket är en lite större uppsättning tecken än vad användaren har, men det kan vara tillräckligt bra.

Svar

Du kan använda fullständig regex för att hitta specialtecken inom hakparenteser om du letar efter ett tecken som är ett specialtecken. En bra resurs som övar, lär dig och kontrollerar ditt reguljära uttryck är regex101.com .

Detta använder Perl-reguljära uttryck, som kan användas med GNU grep med alternativet -P:

grep -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" ^^^ 

Observera att du behöver två backsl aska framför dollartecknet, eftersom det har en speciell betydelse i skalet, och det första bakåtvända snedstrecket kommer undan det för skalet. (Med bara en bakåtvänd snedstreck framför, skulle skalet ta bort bakåtvända snedstrecket, grep skulle se ett oskyddat dollartecken som betyder slutet på raden och matcha alla inmatningsrader.)

Om din terminal stöder färger, kasta också färger,

grep --color=auto -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" 

Här är förklaringen till min regex från 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 ’ för att undkomma stängningen ] med bakåtvänd snedstreck. backslash är inte speciellt inom parentesuttryck. För att ha ett ] inom ett parentesuttryck måste det vara först: []other], inte [ot\]her]. Det ’ skiljer sig från PCRE som regex101 beskriver som standard.
  • Det skulle fungera med pcregrep eller GNU grep -P. Och på sätt och vis är Perl-beteendet enklare: en backslash gör alltid en speciell karaktär normal.
  • Korrigerad till -P, ledsen för det, jag får blandat -E och -P

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *