grep - reconhece o retorno de carro como nova linha

2

Eu quero pesquisar um servidor web executando unix para arquivos php contendo uma string específica. Normalmente eu uso esses comandos para fazer isso:

find . -name "*.php" -print0 | xargs -0 grep -H -i "the string to search for"

Isto irá encontrar qualquer arquivo php contendo "a string para procurar", e imprimir o nome do arquivo e a linha na qual a correspondência foi feita.

Isso funcionou muito bem até agora, mas agora encontrei um servidor em que todos os scripts php não possuem feeds de linha, mas apenas retornos de carro. grep parece não reconhecer o retorno de carro como nova linha, então o comando acima irá imprimir todo o conteúdo de um arquivo se houver uma correspondência dentro dele, em vez de apenas imprimir a linha.

Qualquer ajuda seria muito apreciada!

    
por quano 30.09.2011 / 22:28

3 respostas

2

Que tal usar (grep no meu Ubuntu, tenho certeza que a maior parte do grep tem essa bandeira)

  -o, --only-matching
         Print only the matched (non-empty) parts of a matching line, with each such >part on a separate output line.

junto com

  -b, --byte-offset
         Print  the  0-based byte offset within the input file before each line of >output.  If -o (--only-matching) is specified, print the offset of
         the matching part itself.

Então você tem o nome do arquivo e a parte dele que você quer.

Além disso, como você conseguiu manipular seus arquivos assim? Eu tentei usar VI para substituir novas linhas apenas com CR. Mas isso fez com que grep e cat se comportassem muito estranhamente.

conteúdo do teste de arquivo

gggggggggggggggggggg^Mggggggggasdfgggggggg^Mgggggggggggggggggggg

~/test$ grep asdf test

gggggggggggggggggggg

~/test$ cat test

gggggggggggggggggggg

Parece normal no bloco de notas

    
por 30.09.2011 / 23:00
2

Infelizmente, o grep não fará o que você deseja. Não há uma opção de linha de comando para que ele reconheça o caractere CR como um separador de linha. No entanto, você pode fazer o que quiser com um pouco de awk! Tente isto:

find . -name '*.php' -print0 | \
    xargs -0 awk -v RS="\r" '/string to search for/ {print FILENAME ": " $0}'

O Awk não é tão rápido quanto o grep, portanto, esse método pode demorar muito mais dependendo do número de arquivos e de seus tamanhos. Pode valer a pena simplesmente converter todos os finais de linha dos seus arquivos PHP se você for fazer muito grepping neles. Se você não tem um utilitário conveniente disponível para fazer isso para você, este script de shell deve fazê-lo:

find . -name '*.php' | while read PHPFILE; do
    mv "$PHPFILE" "$PHPFILE".orig
    awk -v RS="\r" '{print $0}' < "$PHPFILE".orig > "$PHPFILE"
done
    
por 01.10.2011 / 01:18
1

E se você fizer algo assim?

for i in 'find . -name "*.php" -print' ; do grep -H -i "the string to search for" $i 2>/dev/null >/dev/null ; if [ $? -eq 0 ] ; then echo $i ; fi ;  done ;

então você só deve obter a saída do arquivo que tem o que você está procurando.

    
por 30.09.2011 / 22:37