Como grep duas vezes?

2
[user@notebook ~]$ printf 'adgaa alpha lajsd assa ><>4 saf\n63SXYZae fkrk safXYZek\nsaf betf!%saa sDGFXYZFalf\n'
adgaa alpha lajsd assa ><>4 saf
63SXYZae fkrk safXYZek
saf betf!aa sDGFXYZFalf
[user@notebook ~]$ 
[user@notebook ~]$ printf 'adgaa alpha lajsd assa ><>4 saf\n63SXYZae fkrk safXYZek\nsaf betf!%saa sDGFXYZFalf\n' | grep SOMEMAGIC
63SXYZae fkrk safXYZek
[user@notebook ~]$ 

Pergunta: como posso grep apenas para as linhas que possuem uma determinada string duas vezes? Neste exemplo, a string era "XYZ". Entre as duas cordas, poderia haver qualquer coisa.

    
por freaking-good-question 06.03.2015 / 17:06

2 respostas

2

Grepping duas vezes não lhe traria nenhum benefício. Eu usaria o egrep em combinação com um regex que combine com o que você precisa.

ps ax | egrep '(a.*){2}'

Isso lhe daria todos os processos, que têm o 'a' duas vezes. É claro que você pode usar isso em qualquer tipo de entrada que o egrep possa ler.

    
por 06.03.2015 / 17:21
0

Com expressões regulares, você pode fazer referência a um padrão% ( agrupado ou você pode especificar que uma correspondência deve ) repeat { it. A diferença entre um e outro é significativa. Para um exemplo simples, considere a string:

baa

... quando comparado com os dois padrões a seguir:

\([ba]\)\{2\}
\([ba]\)

Para o primeiro, o agrupamento é irrelevante porque o padrão procura um único caractere - ao especificar repetições, o agrupamento é importante apenas por conter uma subexpressão completa à qual a repetição pode se referir. E assim, para este simples caso de exemplo ...

 [ba]\{2\}

... e ...

\([ba]\)\{2\}

... são sinônimos e podem ser interpretados como significando que o mecanismo de correspondência deve procurar a sequência mais longa e mais à esquerda na entrada composta de dois caracteres - <<> b ou . A repetição aplica-se ao padrão , o que faz o corresponder e não ao conteúdo da correspondência. Então isso significa literalmente:

[ba][ba]

.... da mesma maneira ...

\(a.*\)\{2\}

... significa ...

a.*a.*

... o que funcionaria bem para o caractere único a , mas que não é um bom exemplo de como corresponder uma string combinada pela segunda vez.

Para nossa amostra de entrada, isso fica ...

ba

Mas a referência de volta é muito diferente - é uma referência ao conteúdo da correspondência . O simples exemplo de caso fica ...

aa

... porque essa é a string mais longa e mais à esquerda na entrada que é composta por um caractere que corresponde ao padrão } da subexpressão e que é imediatamente seguido por em si - não ao padrão correspondente o personagem.

Então você quer:

\(pattern\).*

Porque uma expressão regular padrão e a string com a qual ela combina não são as mesmas - senão não teríamos muita chamada para usar expressões regulares em primeiro lugar. Para demonstrar a diferença com um exemplo de entrada um pouco mais complicado, considere o seguinte:

printf %s\n 123ABC321 123ABC123 321ABC321 |
grep '\([123]\{3\}.*\)\{2\}'

O [ba] acima será impresso:

123ABC321
123ABC123
321ABC321

... porque em todos os casos o padrão é correspondido com sucesso duas vezes. Mas se a linha grep foi substituída por:

grep '\([123]\{3\}\).*'

... só imprimiria ...

123ABC123
321ABC321
    
por 07.03.2015 / 07:07

Tags