Procura por caracteres especiais usando grep

6

Eu quero procurar as linhas que contenham qualquer um dos seguintes caracteres:

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

Estou familiarizado com o grep. Mas com este conjunto de personagens, é um pouco complicado e eu prefiro pedir ajuda.

    
por user9371654 17.08.2018 / 16:53

3 respostas

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

Dentro de uma expressão entre colchetes, [...] , muito poucos caracteres são "especiais" (apenas um subconjunto muito pequeno, como ] , - e ^ , e as três combinações [= , [: e [. ). Ao incluir ] em [...] , o ] deve vir primeiro (possivelmente após um ^ ). Optei por colocar o ] primeiro e o [ por simetria.

A única outra coisa a lembrar é que uma única string entre aspas não pode incluir uma aspa simples, então usamos aspas duplas em torno da expressão. Como usamos uma string com aspas duplas, o shell vai procurar coisas para expandir. Por esse motivo, escapamos do $ as \$ , o que fará com que o shell forneça um literal $ para grep , e escapamos de ! as \! , já que é uma expansão de histórico em bash (somente em bash shells interativos).

Você gostaria de incluir uma barra invertida no conjunto, você teria que escapar como \ para que o shell forneça uma única barra invertida para grep . Além disso, se você quiser incluir um backtick ' , ele também deve ser escapado como \' , já que inicia uma substituição de comando.

O comando acima iria extrair qualquer linha que contivesse pelo menos um dos caracteres na expressão entre colchetes.

Usando uma única string entre aspas em vez de uma string entre aspas duplas, que contorna a maioria dos incômodos com os caracteres que o shell interpreta:

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

Aqui, a única coisa a lembrar, além da colocação do ] , é que uma única string entre aspas não pode incluir uma aspa simples, então usamos uma concatenação de três strings:

  1. '[]:/?#@!$&'
  2. "'"
  3. '()*+,;=%[]'
por 17.08.2018 / 17:04
5

Você pode usar a classe de caractere [:punct:] se não se importar que ela também corresponda a outros caracteres especiais e de pontuação:

grep '[[:punct:]]' file
    
por 17.08.2018 / 17:01
4

Você pode usar o regex completo para encontrar caracteres especiais dentro de colchetes se estiver procurando por um caractere que seja um caractere especial. Um ótimo recurso praticando, aprendendo e verificando sua Expressão Regular é regex101.com .

Isto usa expressões regulares Perl, que podem ser usadas com o GNU grep com a opção -P :

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

Note que você precisa de duas barras invertidas na frente do cifrão, já que tem um significado especial no shell, e a primeira barra invertida irá escapar para o shell. (Com apenas uma barra invertida na frente, o shell removeria a barra invertida, grep veria um sinal de dólar sem escape significando fim de linha e corresponderia a qualquer linha de entrada.)

Se o seu terminal suportar cores, ative também as cores

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

Aqui está a explicação do meu regex de 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)
    
por 17.08.2018 / 17:31