Costumo usar o grep para encontrar arquivos com uma certa entrada como esta:
grep -R 'MyClassName'
O bom é que ele retorna os arquivos, seu conteúdo e marca a string encontrada em vermelho. O ruim é que eu também tenho arquivos enormes, nos quais todo o texto é escrito em uma única linha grande. Agora, o grep gera muito quando encontra texto nesses arquivos grandes. Existe uma maneira de limitar a saída para, por exemplo, 5 palavras à esquerda e à direita? Ou talvez limite a saída para 30 letras à esquerda e à direita?
command-line
text-processing
grep
Sócrates
fonte
fonte
cut
cut
, pois ele só se divide por delimitador ou por contagem de caracteres. Embora quando encontro uma linha comMyClassName
ela, ela esteja em qualquer lugar da linha e nem sempre na mesma posição. Além disso, pode haver uma variação de caracteres na frente e atrás, o que quebra a possibilidade de dividir por delimitador.MyClassName
, quero obter como resultado o nome do arquivo e os caracteres x à esquerda e à direita. x é qualquer número que forneço, por exemplo 30. O restante do conteúdo do arquivo deve ser ignorado. Isso é para obter um contexto para os arquivos correspondentes e limitar a sobrecarga.cut
se houvesse três arquivos com a seguinte entrada:oiadfaosuoianavMyClassNameionaernaldfajd
e/(/&%%§%/(§(/MyClassName&((/$/$/(§/$&
epublic class MyClassName { public static void main(String[] args) { } }
?Respostas:
grep
em si só tem opções de contexto com base em linhas. Uma alternativa é sugerida por este post da SU :Como outra alternativa, sugiro
fold
o texto e depois o saudo, por exemplo:A
-s
opção fará com que asfold
palavras sejam enviadas para a próxima linha, em vez de se separarem.Ou use outra maneira de dividir a entrada em linhas com base na estrutura da sua entrada. (A postagem da SU, por exemplo, lidou com JSON, portanto, usar
jq
etc. para imprimir egrep
... ou apenas usarjq
para fazer a filtragem por si só ... seria melhor do que qualquer uma das duas alternativas fornecidas acima.)Este método GNU awk pode ser mais rápido:
-v RS=...
) e no número de caracteres no contexto (-v n=...
)FNR > 1
) é aquele em que o awk encontrou uma correspondência para o padrão.n
caracteres à direita da linha anterior (p
) en
caracteres iniciais da linha atual (substr($0, 0, n)
), juntamente com o texto correspondente da linha anterior (que éprt
)p
eprt
após a impressão, então o valor que definimos é usado pela próxima linhaRT
é um GNUism, é por isso que isso é específico do GNU awk.Para pesquisa recursiva, talvez:
fonte
fold
método pode ser usado apenas se você tiver certeza de que a sequência pesquisada não aparece na borda, caso contrário, ela ficará ocultagrep
.gawk
. Infelizmente, o comando sugeridofind
produz resultados aleatórios e sem nomes de arquivos, quando executado no meu sistema. Além disso, não sou fluente o suficienteawk
para analisar corretamente o comando. Atualmente, o Regex em combinação comgrep
resolve o problema talvez não seja rápido, mas confiável. Mais uma vez, muito obrigado.RT
prefixos etc. deveriam ser usados.O uso de correspondência apenas em combinação com outras opções (veja abaixo) pode estar muito próximo do que você está procurando, sem a sobrecarga de processamento da regex mencionada na outra resposta
fonte
MyClassName
. Portanto, o contexto está ausente.grep -RnHo "MyClassName"
egrep -Rno "MyClassName"
tem a mesma saída.-o
sinalizador pode ser interessante se o regex tiver alguma parte variável. Para uma sequência fixa, é inútil imprimi-la sempre. É provável que o OP esteja interessado em um contexto próximo.-B 1
) ou depois (-A 1
). Lamento não poder ajudar mais.