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

cutcut, ya que solo se divide por delimitador o por recuento de caracteres. Aunque cuando encuentro una línea conMyClassNameella, 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.MyClassNamese 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.cutsi hay tres archivos con la siguiente entrada:oiadfaosuoianavMyClassNameionaernaldfajdy/(/&%%§%/(§(/MyClassName&((/$/$/(§/$&ypublic class MyClassName { public static void main(String[] args) { } }?Respuestas:
grepsolo tiene opciones de contexto basadas en líneas. Esta publicación SU sugiere una alternativa :Como otra alternativa, sugeriría
foldel texto y luego lo grepé, por ejemplo:La
-sopción hará quefoldlas 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
jqetc. para imprimir bonitas ygrep... o simplemente usarjqpara 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.nlos caracteres finales de la línea anterior (p) ynlos caracteres iniciales de la línea actual (substr($0, 0, n)), junto con el texto coincidente de la línea anterior (que esprt)pyprtdespués de imprimir, entonces el valor que establecemos es usado por la siguiente líneaRTes un GNUismo, es por eso que es GNU awk-específico.Para la búsqueda recursiva, tal vez:
fuente
foldmé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 confindresultados aleatorios y sin nombres de archivo, cuando se ejecuta en mi sistema. Además, no soy lo suficientemente fluido comoawkpara analizar adecuadamente el comando. Actualmente, Regex en combinación congrepresuelve el problema tal vez no sea rápido, pero confiable. De nuevo muchas gracias.RTy 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.-obandera 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.