Chci vyhledat řádky, které obsahují některý z následujících znaků:

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

odpověď

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

V hranatém výrazu [...] je velmi málo znaků “ speciální “ (pouze velmi malá podmnožina, jako ], - a ^ a tři kombinace [=, [: a [.). Při zahrnutí ] do [...] musí ] být na prvním místě (pravděpodobně po ^). Rozhodl jsem se dát ] jako první a [ poslední pro symetrii.

Jediná další věc, kterou si musím pamatovat, je že řetězec s jednou uvozovkou nemůže obsahovat jedinou uvozovku, takže kolem výrazu používáme uvozovky. Jelikož používáme řetězec s dvojitou uvozovkou, shell se v něm bude hrabat, aby se věci mohly rozšířit. Z tohoto důvodu unikneme $ jako \$, což způsobí, že shell dá doslovný $ to grep a my unikneme ! jako \! tak, jak to je historie rozšíření v bash (pouze v interaktivních bash skořápkách).

Chcete zahrnout zpětné lomítko do set, museli byste jej uniknout jako \\, aby prostředí dalo jedno zpětné lomítko grep. Také pokud chcete zahrnout backtick `, musí také uniknout jako \`, protože jinak spustí nahrazení příkazu.

Příkaz výše by extrahovalo jakýkoli řádek, který obsahoval alespoň jeden ze znaků v hranatém výrazu.


Použití řetězce s jednoduchou uvozovkou namísto řetězce s dvojitou uvozovkou, který obchází většinu obtěžování jaké znaky interpretuje shell:

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

Zde je kromě pamětí ], je to, že jeden citovaný řetězec nemůže obsahovat jedinou citaci, takže místo toho použijeme zřetězení tří řetězců:

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

Jiným přístupem by bylo použití třídy znaků POSIX [[:punct:]]. To odpovídá jednomu znaku ze sady !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~, což je větší sada než to, co je uvedeno v otázce (dále obsahuje "-.<>^_`{|}~), ale jsou to všechny “ interpunkční znaky „, které POSIX definuje.

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

Komentáře

  • @ilkkachu ‚ jsem $ tam! Díky!
  • Při pokusu o provedení příkazu se mi zobrazí tato chyba bash: !\: event not found.
  • @ user9371654 Darn bash! 🙂 Unikněte také ! … nebýt bash uživatel, na který jsem zapomněl. Aktualizuji …
  • "[\!]" expanduje na [\!] i když je povoleno rozšíření historie, shodovalo by se to i na zpětném lomítku. ‚ d potřebujete jednoduché uvozovky nebo použít \! outsi počet citací.
  • Upozorňujeme, že ‚ to není jen bash, zsh má také tuto nepříjemnou vlastnost zděděnou z csh. v csh také ! speciální uvnitř '...' a také v případě, že není interaktivní. V csh (na rozdíl od bash nebo zsh) by však použití "\!" fungovalo zde (zpětné lomítko je odstraněno).

Odpověď

Můžete použít [:punct:] třídu znaků, pokud nevadí, že odpovídá i jiným interpunkčním a speciálním znakům:

grep "[[:punct:]]" file 

Komentáře

  • punct třída znaků (ne makro) odpovídá !"#$%&'()*+,-./:;<=>?@[\]^_ {|} ~ `v národním prostředí C, což je mírně velká sada znaků než co má uživatel, ale může to být dost dobré.

Odpověď

K vyhledání můžete použít plný regex speciální znaky v hranatých závorkách, pokud hledáte jeden znak, který je zvláštním znakem. Skvělým zdrojem pro nácvik, učení a kontrolu regulárních výrazů je regex101.com .

Používá regulární výrazy Perlu, které lze použít s GNU grep s možností -P:

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

Upozorňujeme, že potřebujete dva backsl popel před znakem dolaru, protože má v shellu zvláštní význam a první zpětné lomítko mu pro shell unikne. (S pouhým jedním zpětným lomítkem vpředu by shell odstranil zpětné lomítko, grep by viděl neoznačený znak dolaru, což znamená konec řádku, a shodoval by se s jakýmkoli vstupním řádkem.)

Pokud váš terminál podporuje barvy, použijte také barvy,

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

Zde je vysvětlení mého regulárního výrazu z 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) 

Komentáře

  • Ne, se standardním ERE ‚ nemůžete uniknout závěru ] se zpětným lomítkem. zpětné lomítko není ve výrazech hranaté závorky zvláštní. Chcete-li mít ] uvnitř výrazu závorky, musí být nejprve: []other], nikoli [ot\]her]. To ‚ se liší od PCRE, které regex101 popisuje ve výchozím nastavení.
  • Fungovalo by to s pcregrep nebo GNU grep -P. A v jistém smyslu je chování Perlu přímočařejší: zpětné lomítko vždy dělá speciální znak normálním.
  • Opraveno na -P, omlouvám se, dostanu smíšené -E a -P

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *