2010-04-09 21 views
9

Estaba intentando hacer una sustitución sed en un archivo binario, pero estoy empezando a creer que no es posible. Esencialmente lo que quería hacer era similar a la siguiente:reemplazo de sed binario

sed -bi "s/\(\xFF\xD8[[:xdigit:]]\{1,\}\xFF\xD9\)/\1/" file.jpg 

La lógica me gustaría conseguir es: escanear a través de un archivo binario hasta que el código hexadecimal FFD8, continuar leyendo hasta FFD9, y sólo a salvar lo que había entre ellos (descarta la basura antes y después, pero incluye FFD8 y FFD9 como la parte guardada del archivo)

¿Hay una buena manera de hacerlo? Incluso si no está usando sed?

EDIT: Solo estaba jugando y encontré la manera más limpia de hacerlo, IMO. Soy consciente de que esta declaración grep actuará codicioso.

hexdump -ve '1/1 "%.2x"' dirty.jpg | grep -o "ffd8.*ffd9" | xxd -r -p > clean.jpg 
+0

Siempre tenga cuidado con las coincidencias falsas al agrupar patrones en lo que esencialmente son datos aleatorios, como una secuencia binaria comprimida. – dwarring

+0

@snoopy - (1) ¿hay una mejor solución? (2) si no, ¿qué se necesita hacer para mejorar esto? ¿Detener la búsqueda una vez que se llega al "final de los metadatos"? – DVK

+0

Depende exactamente de lo que esté haciendo pero el módulo CPAN Imagen :: EXIF ​​le permite extraer y cambiar metadatos. Podría ser de utilidad aquí. – dwarring

Respuesta

6

bbe es un "sed para archivos binarios", y debería funcionar de manera más eficiente para archivos binarios grandes que para hexadecimales/reconstruir.

Un ejemplo de su uso:

$ bbe -e 's/original/replaced/' infile > outfile 

más información sobre el man page.

1

sed podría ser capaz de hacerlo, pero podría ser complicado. Aquí hay un script en Python que hace lo mismo (tenga en cuenta que edita el archivo en el lugar, que es lo que supongo que quiere hacer sobre la base de su secuencia de comandos sed):

import re 

f = open('file.jpeg', 'rb+') 
data = f.read() 
match = re.search('(\xff\xd8[0-9A-fa-f]+)\xff\xd9', data) 
if match: 
    result = match.group(1) 
    f.seek(0) 
    f.write(result) 
    f.truncate() 
else: 
    print 'No match' 
f.close() 
3

Is there a good way to do this

sí de Por supuesto, use una herramienta de edición de imágenes como ImageMagick (busque en la red para Linux jpeg, exif editor, etc.) que sepa cómo editar los metadatos jpg. Estoy seguro de que puedes encontrar una herramienta que te convenga. No intentes hacer esto de la manera difícil. :)

+0

de acuerdo, esto es esencialmente datos binarios aleatorios, por lo que tiene un 1/(2 ** 16) de obtener un falso positivo al buscar cualquier secuencia de 2 bytes. Eso es aproximadamente una vez cada 65,000 de datos. – dwarring

+0

exiftool (http://search.cpan.org/dist/Image-ExifTool/exiftool) es la aplicación clave para los metadatos multimedia. – daxim

+0

Copiando mi comentario anterior aquí: FYI, el propósito de esta pregunta era hacer una talla de archivo manual en un escenario de INCURSIÓN 5. Al agarrar rayas y trozos obtendrás datos antes y después del jpg (o cualquier otro archivo). Esto fue para limpiarlo. – Ryan

1

Además, este Perl podría funcionar (no probado, caveat.emptor) ... si no se instala Python :)

open(FILE, "file.jpg") || die "no open $!\n"; 
while (read(FILE, $buff, 8 * 2**10)) { 
    $content .= $buff; 
} 
@matches = ($content =~ /(\xFF\xD8[:xdigit:]+?\xFF\xD9)/g; 
print STDOUT join("", @matches); 

Es necesario añadir binmode(FILE); binmode(STDOUT); en DOS o VMS después de la open() llamada: no es necesario en Unix.

+0

lo siento DVK - ese era yo. Me han picado los errores al tratar de grep para patrones cortos en datos binarios. Simplemente piense que hay una buena posibilidad de que este desajuste, ya sea en uno u otro de los anclajes o en un patrón fantasma al azar. Solo pienso que Tarde o temprano, el OP probablemente terminará con el extraño jpeg codificado y ¡se preguntará por qué! También degradaron a otros por la misma razón. – dwarring

+1

Si está diciendo que OP tiene un problema XY, presente una solución mejor que una expresión regular antes de descargar soluciones regex como "malas". Si esta respuesta tiene un error, por favor indíquelo. Si hay un patrón específico donde el enfoque de la expresión regular fallaría, por favor aclare eso como una respuesta (otra vez XY) – DVK

+1

Además, tenga en cuenta que esta solución NO cambia el archivo jpg. Simplemente resultados encontraron cadenas (que supongo que podrían ser metadatos) a estándar para posterior redirección/consumo – DVK