grep caracteres circundantes de uma correspondência

8

Estou procurando encontrar e substituir dentro de um dump de banco de dados gigante, e não está fazendo o que acho que deveria acontecer. Gostaria de grep para minha string de destino no arquivo e, em seguida, ver os 8 caracteres ao redor ou mais (talvez seja necessário ajustar esse número, dependendo). Como eu posso fazer isso?

A razão pela qual não posso ocular isso é porque existem muitas centenas, senão milhares de partidas. Quero obter um número de caracteres ao redor da string e, em seguida, canalizá-la uniqou algo para ver por que minha localização e substituição está tendo comportamentos inesperados.

Além disso, pode haver várias correspondências na mesma linha!

user394
fonte
Não é um arquivo de texto?
enzotib
É verdade, mas mesmo as correspondências são um arquivo muito grande para o globo ocular.
user394

Respostas:

12

O modo bruto de usar grepseria algo como

grep -o "....yourtext...." /path/to/the/dump.sql

O número de pontos corresponde ao número de caracteres antes / depois do texto em grep. A -oopção produz grepapenas as correspondências, não as linhas inteiras.

Para usar uniqna saída, lembre-se de que você deve classificar a saída primeiro. Normalmente, você faria

grep . . . | sort | uniq

Se você estiver interessado na contagem de hits de cada partida, poderá obter resultados agradáveis ​​usando

grep . . . | sort | uniq -c | sort -n
rozcietrzewiacz
fonte
Bruto? Totalmente sofisticado!
user394
11
Você poderia expandir sobre isso um pouco usando o operador de repetição: grep -o '.\{8\}yourtext.\{8\}'. Isso é um pouco menos vertiginoso do que contar 8 pontos.
Caleb
:) Com bruto, quero dizer que você não brinca com coisas como contar caracteres correspondentes (usando intervalos) ou restringir os conjuntos de caracteres.
rozcietrzewiacz
@Caleb e user394: Isso é exatamente o que eu pretendia não sugerir (e, portanto, chamei meu método de "bruto"). Além disso, não é necessário lembrar da construção do operador repeat - é ainda mais rápido digitar "....." do que ". \ {6 \}".
rozcietrzewiacz
7

A partir da resposta de @rozcietrzewiacz, posso expandir para

pattern="string"
num=8
grep -on ".\{0,$num\}$pattern.\{0,$num\}" input-file
enzotib
fonte
11
O "bruto" dot seqüência está olhando melhor e melhor o tempo todo :)
Caleb
11
@ Caleb: geralmente a resposta "grosseira" é um bom começo, mas às vezes se quer elaborar um pouco sobre ela.
enzotib
11
O método de sequência de pontos não encontrará padrões de alvo justificados para a esquerda ou para a direita; este método será. (+1)
Peter.O
2
PS .. Acabei de notar que ele não captura várias instâncias de padrão na mesma linha (como o OP mencionado) quando o escopo do texto 'exta' à direita do primeiro padrão se sobrepõe ao escopo do texto 'extra' inicial do próximo padrão
Peter.O
@fred: sim, -odá apenas o primeiro jogo quando dois jogos se sobrepõem:echo 'aaabbbccc' | grep -o 'bb
enzotib