Como encontrar uma string fixa com grep?

0

Como encontrar strings fixas com grep se a saída requerida não for mostrada com grep -F ? Por exemplo:

egrep -r 'string1|string2|string3' /var/www/http

com isso, o que devemos usar?

    
por Gurpreet kaur 19.04.2018 / 08:58

3 respostas

2

Use grep -E (a forma moderna para egrep ), portanto, | seja tratado como um operador alternação de expressão regular estendida, mas você precisará fugir de todas as outras expressões regulares operador (como . , ? , * , ^ , $ , \ , [ , ( , ) , { , } ) no seu < em> strings fixas .

Ou use -F e passe as strings uma por linha ou com vários -e s:

grep -Fe string1 -e string2 -e string3

Ou:

grep -F 'string1
string2
string3'

Adicione a opção -x se essas cadeias fixas tiverem que formar toda a linha correspondente (ao contrário de ser encontrada em qualquer lugar dentro da linha sem ela). A maioria das implementações grep também tem uma opção -w para a correspondência palavra , onde, por exemplo, string1 corresponderia dentro de foo string1-2 , mas não dentro de foostring12 .

Para o seu exemplo específico nos comentários, seria:

grep -wE 'Allow from (8\.8\.2\.5|192\.3\.0\.4)|DenyAll'

Ou:

grep -we 'Allow from 8.8.2.5' -e 'Allow from 192.3.0.4' -e 'DenyAll'

Você deseja -w ou -x (supondo que sejam as linhas inteiras, nem mesmo espaços ao redor), caso contrário, também corresponderia a linhas como Allow from 8.8.2.51 .

Você também pode escrever:

grep -xE '[[:space:]]*(Allow from (8\.8\.2\.5|192\.3\.0\.4)|DenyAll)[[:space:]]*'

Para corresponder na linha completa ( -x ), mas permitindo caracteres de espaçamento à esquerda e à direita (usando [[:space:]] em vez de [[:blank:]] para permitir também os caracteres CR encontrados no final das linhas provenientes do MS-DOS mundo).

Para procurar essas cadeias fixas em qualquer ponto da linha, mas não nos comentários, você precisa garantir que a parte da linha que leva a essas cadeias fixas não contenha # caracteres. Então, algo como:

grep -wE '^[^#]*(Allow from (8\.8\.2\.5|192\.3\.0\.4)|DenyAll)'

Observe que o -w não se aplica a Allow quando se aplica a toda a string correspondente. Por isso, seria igual a GAllow from , por exemplo. Algumas grep implementações suportam \< , \> para corresponder explicitamente a limites de palavras (também conhecido como \b em alguns):

grep -E '^[^#]*\<(Allow from (8\.8\.2\.5|192\.3\.0\.4)|DenyAll)\>'

Observe também que, em apache2 , as diretivas de configuração são insensíveis a maiúsculas e minúsculas e qualquer número de espaços em branco é permitido entre as palavras. Além disso, eu suspeito que você quis dizer Deny from all em vez de DenyAll , então talvez você queira:

grep -iE '^[^#]*\<(allow[[:blank:]]+from[[:blank:]]+(8\.8\.2\.5|192\.3\.0\.4)|deny[[:blank:]]+from[[:blank:]]+all)\>'
    
por 19.04.2018 / 10:36
0

Os pipes | precisam ser escapados \| da seguinte forma:

grep 'string1\|string2\|string3\' /var/www/http
    
por 19.04.2018 / 09:28
0

A questão é que

grep -F -r 'string1|string2|string3' /var/www/http

procuraria a string literal string1|string2|string3 nos arquivos. Note que, desde que você esteja procurando por strings fixas, não há razão para usar egrep (ou grep -E ).

O que você poderia fazer é usar

printf 'string1\nstring2\nstring3\n' | grep -f /dev/stdin -F -r /var/www/http

Isso faria com que grep lesse as strings fixas para casar com a entrada padrão (fornecida por printf ) e as usasse para obter todas as linhas que correspondessem a elas em qualquer arquivo no diretório fornecido.

Qualquer coisa que gere um documento de texto com os padrões em linhas separadas pode substituir o printf acima, incluindo um arquivo de texto simples (que pode ser lido diretamente por grep -f textfile -F ... ).

Exemplo dos seus comentários:

Procure por qualquer uma das strings Allow from 8.8.2.5 , Allow from 192.3.0.4 e DenyAll nos arquivos em $dirpath :

printf 'Allow from 8.8.2.5\nAllow from 192.3.0.4\nDenyAll\n' |
grep -f /dev/stdin -F -r "$dirpath"
    
por 19.04.2018 / 09:24