Hoy tuve que eliminar los primeros 1131 bytes de un archivo mixto de texto / binario de 800 MB, un volcado de subversión filtrado que estoy pirateando para un nuevo repositorio. ¿Cuál es la mejor manera de hacer esto?
Para empezar intenté
dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump
pero después del salto, esto copia el resto del archivo un byte a la vez, es decir, muy lentamente. Al final trabajé, necesitaba 405 bytes para redondear esto a tres bloques de 512 que podía omitir.
dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump
que se completó bastante rápido, pero debe haber habido una manera más simple / mejor? ¿Hay alguna otra herramienta que haya olvidado? ¡Gracias!

ddes la herramienta adecuada para el trabajo: parece que se le ocurrió una solución agradable y elegante para su problema.Respuestas:
Puede cambiar bs y omitir opciones:
De esta manera, la operación puede beneficiarse de un bloqueo mayor.
De lo contrario, podría intentar con tail (aunque no es seguro usarlo con archivos binarios):
Finalmente, puede usar instancias de 3 dd para escribir algo como esto:
donde el primer dd imprime su salida estándar filter.dump; el segundo solo lee 1131 bytes y los tira; luego, el último lee de su entrada estándar los bytes restantes de filter.dump y los escribe en trimmed.dump.
fuente
bs=1131 skip=1: - /No estoy seguro de cuándo
skip_bytesse agregó, pero para omitir los primeros 11 bytes que tiene:Where
iflag=skip_bytesle dice a dd que interprete el valor de laskipopción como bytes en lugar de bloques, lo que lo hace sencillo.fuente
iflag=skip_bytes skip=1234 bs=1MPuede usar un sub-shell y dos
ddllamadas como esta:fuente
Si el sistema de archivos y el kernel de Linux lo admiten, puede probar
fallocatesi desea realizar los cambios en el lugar: en el mejor de los casos, no hay datos IO en absoluto:donde
<magic>depende del sistema de archivos, la versión de Linux y el tipo de archivo (FALLOC_FL_COLLAPSE_RANGEoFALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZEpodría usarse internamente ).fuente
Deberías usar
count=0, eso es simplelseek()siempre que sea posible.Me gusta esto:
ddenviarálseek()el descriptor del archivo de entrada a un desplazamiento de 1131 bytes, y luegocatsimplemente copiará lo que quede para la salida.fuente
Otra forma de eliminar bytes iniciales de un archivo (sin usar
dden absoluto) es usarxxdy /sedotailrespectivamente.fuente
@maxschlepzig solicita un revestimiento en línea. Aquí hay uno en perl. Se necesitan 2 argumentos: desde el byte y la longitud. El archivo de entrada debe estar dado por '<' y la salida estará en stdout:
Si la longitud es mayor que el archivo, se copiará el resto del archivo.
En mi sistema, esto entrega 3.5 GB / s.
fuente
ddno garantiza una lectura completa. Intenta: sí | dd bs = 1024k cuenta = 10 | wc unix.stackexchange.com/questions/17295/…