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!
dd
es 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_bytes
se agregó, pero para omitir los primeros 11 bytes que tiene:Where
iflag=skip_bytes
le dice a dd que interprete el valor de laskip
opción como bytes en lugar de bloques, lo que lo hace sencillo.fuente
iflag=skip_bytes skip=1234 bs=1M
Puede usar un sub-shell y dos
dd
llamadas como esta:fuente
Si el sistema de archivos y el kernel de Linux lo admiten, puede probar
fallocate
si 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_RANGE
oFALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE
podría usarse internamente ).fuente
Deberías usar
count=0
, eso es simplelseek()
siempre que sea posible.Me gusta esto:
dd
enviarálseek()
el descriptor del archivo de entrada a un desplazamiento de 1131 bytes, y luegocat
simplemente copiará lo que quede para la salida.fuente
Otra forma de eliminar bytes iniciales de un archivo (sin usar
dd
en absoluto) es usarxxd
y /sed
otail
respectivamente.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
dd
no garantiza una lectura completa. Intenta: sí | dd bs = 1024k cuenta = 10 | wc unix.stackexchange.com/questions/17295/…