2012-03-15 17 views
5

A continuación verá un pequeño fragmento de coincidencias de la cadena 'octeon' en un volcado de memoria 32b desde un dispositivo de enrutamiento patentado. Como puede ver, contiene algunos ASCII ajustados que se extienden a 16 caracteres del final de la línea, luego cuatro palabras de 32 bits (8 caracteres cada uno, por supuesto), luego el desplazamiento de la dirección.Expresión regular para solo coincidir con el número X de caracteres desde el final de la línea

000b27a0: 41646a75 7374206f 6374656f 6e5f6970 Adjust octeon_ip 
000b2850: 73740a00 00000000 6f637465 6f6e5f72 st......octeon_r 
000b2870: 5f73697a 65000000 6f637465 6f6e5f72 _size...octeon_r 
000b2990: 6164696e 672e0a00 6f637465 6f6e5f72 ading...octeon_r 
000b29b0: 785f7369 7a650000 6f637465 6f6e5f72 x_size..octeon_r 
000b3050: 780a0000 00000000 6f637465 6f6e5f70 x.......octeon_p 
000b3650: 6564204f 6374656f 6e206d6f 64656c0a ed Octeon model. 
000bade0: 20307825 71780a00 6f637465 6f6e5f6c  0x%qx..octeon_l 
000bafd0: 696e6720 4f637465 6f6e2045 78656375 ing Octeon Execu 
000bd710: 6564204f 6374656f 6e204d6f 64656c21 ed Octeon Model! 
000bd950: 4f435445 4f4e2070 61737320 3120646f OCTEON pass 1 do 
000bda20: 6564206f 6374656f 6e206d6f 64656c3a ed octeon model: 

Mientras que los datos contiene información útil, trágicamente, el sistema operativo (HiveOS) no hace ningún intento para asignar memoria de forma contigua o para unirse montones dispares (y por qué deberían hacerlo?), Por lo que la gran mayoría de las la memoria es un montón estéril por ser malcarado.

0004d6b0: 00000000 00000000 00000000 00000000 ................ 
0004d6c0: 00000000 00000000 00000000 00000000 ................ 
0004d6d0: 00000000 00000000 00000000 00000000 ................ 
0004d6e0: 00000000 00000000 00000000 00000000 ................ 
0004d6f0: 00000000 00000000 00000000 00000000 ................ 
0004d700: 00000000 00000000 00000000 00000000 ................ 
0004d710: 00000000 00000000 00000000 00000000 ................ 
0004d720: 00000000 00000000 00000000 00000000 ................ 
0004d730: 00000000 00000000 00000000 00000000 ................ 
0004d740: 00000000 00000000 00000000 00000000 ................ 
0004d750: 00000000 00000000 00000000 00000000 ................ 

me gustaría tirar de forma rápida y eficiente a cabo cuerdas de un cierto tamaño coinciden con alguna patrón de expresión regular arbitraria ([a-zA-z] viene a la mente) Se podría pensar, naturalmente, que la ejecución de la perenne objeto volcado examen favoritos 'cadenas' arrojaría un resultado, pero la utilidad md es una amante cruel - debido a la presencia de las direcciones de los bancos hexadecimales ascii &, identifica cada línea como una 'cadena'.

Claro, todos sabemos que existe una solución de scripting trivial (for line in hexdump: f.write(line[-16:]) + grep '[A-z]' f).

Sin embargo, a veces me impacta la sensación de que debería entender mejor estas expresiones cobardes, opresivas, pero incomprendidas, en lugar de volver a utilizar mis lenguajes de programación novedosos y fáciles de usar. Realmente siento que no puedo empezar a cultivar un cuello de botella real de Unix hasta que haya reemplazado por completo mi vida útil con cadena de herramientas de desarrollo con varias expresiones regulares del editor de flujo y Awk.

¿Cómo se puede coincidir con [a-zA-z] dentro de un cierto número de caracteres desde el final de la línea (en mi caso, 16) - parece una construcción bastante concisa pero con toda la combinación de +,? {16} y, de lo contrario, eso tenía sentido para mí en los últimos minutos han fallado rápidamente.

+0

Quizás he entendido mal la solicitud. ¿Desea obtener los últimos 16 caracteres de cada línea o * extraer solo letras * de los últimos 16 caracteres? – TLS

Respuesta

3

Utilice el interruptor de "no coincidencia" -v:

grep -v \.{16}$ 

Esto tira a todas las líneas que terminan con 16 puntos.

Aquí está la documentación man para ello:

-v, --invert-partido
Invertir el sentido de juego, para seleccionar líneas que no coinciden.

3

¿Hace esto lo que quiere? ".{16}$"

Eso coincidirá con cualquier 16 caracteres del final de la línea. El $ asegura que coincida con el final de la línea.


Después de una inspección más cercana, si se desea extraer sólo las líneas que no son todos los períodos, se puede usar esta expresión regular: "{4}(.*?\w.*?)$" hay un espacio antes de la {4} para que coincida con el delimitador entre los dígitos y el final de la línea. No es técnicamente "solo 16 caracteres", pero dado el conjunto de datos, parece proporcionar el resultado deseado. (Suponiendo que la salida deseada es cualquier línea que tenga un carácter de palabra, que es letras/números/guión bajo)

+0

Estás en el camino correcto, pero aplicar [a-zA-z] {16} $ no funciona :( –

+0

Parece que quieres un resultado siempre que no sea '.......... ...... ', para que pueda usar un lookahead negativo para asegurarse de que no coincida:' (?! [.] {16}). {16} $ ', que debe coincidir con los últimos 16 caracteres cada línea, a menos que sea una cadena de 16 períodos. – VeeArr

+0

@VeeArr - Ejecuté una prueba rápida con '(?! [.] {16}). {16} $', pero eso parece devolver incluso las líneas con todos puntos. – TLS

2

Un truco para filtrar líneas interesantes es completar la selección con cualquier carácter hasta el final de la línea. Aquí selecciono un personaje que no es un punto y que no tiene más de 15 caracteres desde el final de la línea.(Se utiliza expresiones regulares POSIX por lo que debe escribir el cuantificador de repetición entre \ {\} no {})

grep '[^.].\{1,15\}$' 

A continuación, puede dar lugar a la tubería con otra grep para poner a prueba, o se puede adaptar la idea a otra expresión regular:

grep 'abc.\{1,13\}$' 

ma cadena "abc" en los últimos 16 caracteres.

Cuestiones relacionadas