Tengo que buscar algunos archivos JSON en los que la longitud de la línea excede algunos miles de caracteres. ¿Cómo puedo limitar grep para mostrar el contexto hasta N caracteres a la izquierda y a la derecha del partido? Cualquier herramienta que no sea grep también estaría bien, siempre que esté disponible en los paquetes comunes de Linux.
Este sería un ejemplo de salida, para el interruptor grep imaginario Ф :
$ grep -r foo *
hello.txt: Once upon a time a big foo came out of the woods.
$ grep -Ф 10 -r foo *
hello.txt: ime a big foo came of t

Respuestas:
Con GNU
grep:Explicación:
-o=> Imprime solo lo que hiciste coincidir-P=> Usar expresiones regulares de estilo Perl$Ncaracteresfooseguido de 0 seguido por los$Ncaracteres.Si no tienes GNU
grep:Explicación:
Como ya no podemos confiar en
grepser GNUgrep, utilizamosfindpara buscar archivos de forma recursiva (la-racción de GNUgrep). Para cada archivo encontrado, ejecutamos el fragmento de Perl.Interruptores Perl:
-nLee el archivo línea por línea-lElimine la nueva línea al final de cada línea y vuelva a colocarla al imprimir-eTrate la siguiente cadena como códigoEl fragmento de Perl está haciendo esencialmente lo mismo que
grep. Comienza configurando una variable$Nal número de caracteres de contexto que desea. EstoBEGIN{}significa que esto se ejecuta solo una vez al comienzo de la ejecución, no una vez por cada línea en cada archivo.La instrucción ejecutada para cada línea es imprimir la línea si la sustitución de expresiones regulares funciona.
La expresión regular:
^.*?) seguido de.{0,$N}como en elgrepcaso,fooseguido de otro seguido.{0,$N}y finalmente haga coincidir cualquier cosa vieja perezosamente hasta el final de la línea (.*?$).$ARGV:$1.$ARGVes una variable mágica que contiene el nombre del archivo actual que se está leyendo.$1es lo que emparejaron los padres: el contexto en este caso.foosin fallar (ya que.{0,$N}se permite que coincidan cero veces).1 Es decir, prefiera no hacer coincidir nada a menos que esto haga que falle la coincidencia general. En resumen, combine la menor cantidad de caracteres posible.
fuente
| grep fooal final (sin embargo, perdiendo el resaltado del nombre de archivo en el proceso).greppuede especificar colores / aplicaciones coincidentes basados en indicadores aplicados a través de variables de entorno. así que tal vez incluso podrías ganarlos a todos, (sin promesas, ni siquiera estoy seguro de que funcionaría en este caso) pero personalmente no veo la relevancia aquí ... de todos modos ... sigue jugando.zshNo puedo hacer que funcione pasando N = 10 como en el ejemplo. Sin embargo, funciona siexport N=10antes de ejecutar el comando. ¿Alguna idea de cómo ajustar el ejemplo para trabajar con zsh?perl -lne 'print "$ARGV: $_" for /.{0,10}foo.{0,10}/g'Intenta usar este:
-E dice que quieres usar expresiones regulares extendidas
-o dice que solo quieres imprimir la coincidencia
-r grep busca resultados de forma recursiva en la carpeta
REGEX:
{0,10} indica cuántos caracteres arbitrarios desea imprimir
. representa un carácter arbitrario (un personaje en sí no era importante aquí, solo su número)
Editar: Ah, ya veo, que Joseph recomienda casi la misma solución que yo: D
fuente
-Ees significativamente más rápido que-P.Tomado de: http://www.topbug.net/blog/2016/08/18/truncate-long-matching-lines-of-grep-a-solution-that-preserves-color/ y https: // stackoverflow. com / a / 39029954/1150462
El enfoque sugerido
".{0,10}<original pattern>.{0,10}"es perfectamente bueno, excepto que el color de resaltado a menudo está desordenado. He creado un script con una salida similar, pero el color también se conserva:Suponiendo que el script se guarda como
grepl,grepl pattern file_with_long_linesdebería mostrar las líneas coincidentes pero con solo 10 caracteres alrededor de la cadena coincidente.fuente
Tubería estándar
cutcon la-bbandera; Puede indicar la salida de grep a solo bytes 1 a 400 por línea.fuente