dd eliminar rango de bytes

dd eliminar rango de bytes

Dado este archivo

$ cat hello.txt
hello doge world

Me gustaría eliminar un rango de bytes para terminar con esto

$ cat hello.txt
heorld

Me gustaría hacer esto ddsi es posible. La razón es porque ya estoy usando ddpara sobrescribir bytes de esta manera.

printf '\x5E' | dd conv=notrunc of=hello.txt bs=1 seek=$((0xE))

Prefiero volver a escribir en el mismo archivo, pero un archivo de salida diferente estaría bien.

Respuesta1

Es cuestión de especificar el tamaño del bloque, contar y omitir:

$ cat hello.txt
hello doge world
$ { dd bs=1 count=2 ; dd skip=3 bs=1 count=1 ; dd skip=6 bs=1 ; } <hello.txt 2>/dev/null
he orld

Lo anterior utiliza tres invocaciones de dd. El primero obtiene los dos primeros caracteres he. El segundo salta al final helloy copia el espacio que sigue. El tercero salta a la última palabra worldcopiando todo menos el primer carácter.

Esto se hizo conÑUddperoBSDddParece que debería funcionar también.

Respuesta2

# copy the end piece into correct position
dd bs=1 seek=2 skip=12 conv=notrunc if=hello.txt of=hello.txt

# truncate
dd bs=1 seek=6 if=/dev/null of=hello.txt

marcos tiene razon

Respuesta3

Supongo que esto es posible, ddpero es como usar un tanque para matar una mosca. Por qué no

$ printf "%s %s\n" $(head -c 2 hello.txt) $(tail -c 5 hello.txt )
he orld

La -copción significa (para head):

   -c, --bytes=[-]K
          print the first K bytes of each  file;  with  the  leading  '-',
          print all but the last K bytes of each file

y para tail:

   -c, --bytes=K
          output the last K bytes; alternatively,  use  -c  +K  to  output
          bytes starting with the Kth of each file

En general, para eliminar el rango de bytesnorteaXinclusive, correrías

( head -c n-1; head -c -x-1)  )

Por ejemplo, para eliminar del 4º al 12º bytes:

$ (head -c 3 hello.txt; tail -c +11 hello.txt )
hel world

Respuesta4

Perl packy unpackla función son buenos para tratar con cadenas de ancho fijo. Si quieres usar Perl, prueba esto:

$ perl -le '
    ($head,$skip,$tail) = unpack("A2 A5 A*", "hello world");
    ($space) = $skip =~ m/(\s+)/;
    print $head.$space.$tail;
'
he orld

Explicación

  • Dividiremos la cadena en tres partes, $heades el inicio de la cadena hasta el primer byte que queremos eliminar, $skipes el rango de bytes que queremos eliminar, $tailes el resto de la cadena.

  • unpackLa plantilla "A2 A5 A*"dividirá la cadena en tres partes como se explicó anteriormente.

  • Con $skip, obtendremos los espacios que contenga, lo guardaremos en $space.

  • Imprima la concatenación de tres partes para obtener el resultado deseado.

Actualizado

Como no desea ahorrar espacio, la solución parece ser más sencilla:

$ perl -le 'print unpack("A2 x5 A*","hello world")'
heorld

Con cadena actualizada:

$ perl -le 'print unpack("A2 x10 A*","hello doge world")'
heorld

x10en unpackplantilla, lo que significa omitir los 10 bytes en la cadena.

información relacionada