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 dd
si es posible. La razón es porque ya estoy usando dd
para 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 hello
y copia el espacio que sigue. El tercero salta a la última palabra world
copiando todo menos el primer carácter.
Esto se hizo conÑUdd
peroBSDdd
Parece 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
Respuesta3
Supongo que esto es posible, dd
pero 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 -c
opció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 pack
y unpack
la 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,
$head
es el inicio de la cadena hasta el primer byte que queremos eliminar,$skip
es el rango de bytes que queremos eliminar,$tail
es el resto de la cadena.unpack
La 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
x10
en unpack
plantilla, lo que significa omitir los 10 bytes en la cadena.