A menudo uso grep para encontrar archivos que tengan una determinada entrada como esta:
grep -R 'MyClassName'
Lo bueno es que devuelve los archivos, su contenido y marca la cadena encontrada en rojo. Lo malo es que también tengo archivos enormes donde todo el texto está escrito en una sola línea grande. Ahora grep genera demasiados resultados al encontrar texto dentro de esos archivos grandes. ¿Hay alguna forma de limitar la salida a, por ejemplo, 5 palabras a la izquierda y a la derecha? ¿O tal vez limite la salida a 30 letras a la izquierda y a la derecha?
command-line
text-processing
grep
Sócrates
fuente
fuente
cut
cut
, ya que solo se divide por delimitador o por recuento de caracteres. Aunque cuando encuentro una línea conMyClassName
ella, puede estar en cualquier parte de la línea y no siempre en la misma posición. Además, puede haber una variación de caracteres en la parte delantera y trasera de la misma, lo que rompe la posibilidad de dividir por delimitador.MyClassName
se ha encontrado una línea positiva con , quiero obtener como resultado el nombre del archivo y los caracteres x a la izquierda y a la derecha. x es cualquier número que proporcione, por ejemplo 30. El resto del contenido del archivo se ignorará. Esto es para obtener un contexto para los archivos coincidentes y limitar la sobrecarga.cut
si hay tres archivos con la siguiente entrada:oiadfaosuoianavMyClassNameionaernaldfajd
y/(/&%%§%/(§(/MyClassName&((/$/$/(§/$&
ypublic class MyClassName { public static void main(String[] args) { } }
?Respuestas:
grep
solo tiene opciones de contexto basadas en líneas. Esta publicación SU sugiere una alternativa :Como otra alternativa, sugeriría
fold
el texto y luego lo grepé, por ejemplo:La
-s
opción hará quefold
las palabras de inserción pasen a la siguiente línea en lugar de dividirse en el medio.O utilice alguna otra forma de dividir la entrada en líneas según la estructura de su entrada. (La publicación SU, por ejemplo, se ocupó de JSON, por lo que usar
jq
etc. para imprimir bonitas ygrep
... o simplemente usarjq
para hacer el filtrado por sí mismo ... sería mejor que cualquiera de las dos alternativas dadas anteriormente).Este método GNU awk podría ser más rápido:
-v RS=...
) y la cantidad de caracteres en contexto (-v n=...
)FNR > 1
) es uno donde awk encontró una coincidencia para el patrón.n
los caracteres finales de la línea anterior (p
) yn
los caracteres iniciales de la línea actual (substr($0, 0, n)
), junto con el texto coincidente de la línea anterior (que esprt
)p
yprt
después de imprimir, entonces el valor que establecemos es usado por la siguiente líneaRT
es un GNUismo, es por eso que es GNU awk-específico.Para la búsqueda recursiva, tal vez:
fuente
fold
método solo se puede usar si está seguro de que la cadena buscada no aparece en el borde, de lo contrario se ocultaríagrep
.gawk
. Desafortunadamente, el comando sugerido confind
resultados aleatorios y sin nombres de archivo, cuando se ejecuta en mi sistema. Además, no soy lo suficientemente fluido comoawk
para analizar adecuadamente el comando. Actualmente, Regex en combinación congrep
resuelve el problema tal vez no sea rápido, pero confiable. De nuevo muchas gracias.RT
y prefijo, etc. debían usarse.El uso de solo coincidencia en combinación con algunas otras opciones (ver más abajo), podría estar muy cerca de lo que está buscando, sin la sobrecarga de procesamiento de expresiones regulares mencionada en la otra respuesta
fuente
MyClassName
. Por lo tanto, falta el contexto.grep -RnHo "MyClassName"
ygrep -Rno "MyClassName"
tienen la misma salida.-o
bandera podría ser interesante si la expresión regular tuviera alguna parte variable. Para una cadena fija, es inútil imprimirla cada vez. Lo más probable es que OP esté interesado en el contexto cercano.-B 1
) o después (-A 1
). Lamento no poder ser de más ayuda.