Dado este arquivo
$ cat hello.txt
hello doge world
Eu gostaria de remover um intervalo de bytes para acabar com isso
$ cat hello.txt
heorld
Eu gostaria de fazer isso dd
se possível. A razão é porque eu já estou usando dd
para sobrescrever bytes desta maneira
printf '\x5E' | dd conv=notrunc of=hello.txt bs=1 seek=$((0xE))
Prefiro escrever de volta no mesmo arquivo, mas um arquivo de saída diferente seria adequado.
Responder1
É uma questão de especificar o tamanho do bloco, contar e pular:
$ 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
O texto acima usa três invocações de dd
. O primeiro recebe os dois primeiros caracteres he
. O segundo pula para o final hello
e copia o espaço a seguir. O terceiro pula para a última palavra, world
copiando tudo, exceto o primeiro caractere.
Isso foi feito comGNUdd
masBSDdd
parece que deveria funcionar também.
Responder2
# 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
Responder3
Acho que isso é possível, dd
mas é como usar um tanque para matar uma mosca. Por que não
$ printf "%s %s\n" $(head -c 2 hello.txt) $(tail -c 5 hello.txt )
he orld
A -c
opção 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
e para tail
:
-c, --bytes=K
output the last K bytes; alternatively, use -c +K to output
bytes starting with the Kth of each file
Em geral, para remover o intervalo de bytesnparaxinclusive, você correria
( head -c n-1; head -c -x-1) )
Por exemplo, para remover do 4º ao 12º bytes:
$ (head -c 3 hello.txt; tail -c +11 hello.txt )
hel world
Responder4
Perl pack
e unpack
função são bons para lidar com strings de largura fixa. Se você quiser usar Perl
, tente isto:
$ perl -le '
($head,$skip,$tail) = unpack("A2 A5 A*", "hello world");
($space) = $skip =~ m/(\s+)/;
print $head.$space.$tail;
'
he orld
Explicação
Vamos dividir a string em três partes,
$head
é o início da string até o primeiro byte que queremos remover,$skip
é o intervalo de bytes que queremos remover,$tail
é o resto da string.unpack
O modelo"A2 A5 A*"
dividirá a string em três partes, conforme explicado acima.Com
$skip
, obteremos quaisquer espaços nele, salve-os em$space
.Imprima a concatenação de três partes para obter o resultado desejado.
Atualizada
Como você não quer economizar espaço, a solução parece ser mais fácil:
$ perl -le 'print unpack("A2 x5 A*","hello world")'
heorld
Com string atualizada:
$ perl -le 'print unpack("A2 x10 A*","hello doge world")'
heorld
x10
no unpack
modelo, o que significa pular os 10 bytes na string.