Grava n bytes de um arquivo em outro no Bash

6

Olá, como posso gravar n bytes de um arquivo em um novo arquivo a partir da k position usando o Bash?

  • Por exemplo, se n = 60, k = 1 e tamanho do arquivo = 100, então: o segundo arquivo consistiria do primeiro byte até o 60th byte e teria 60 bytes de tamanho
  • Por exemplo, se n = 40, k = 61 e tamanho do arquivo = 100, então: o segundo arquivo consistiria do 61º byte até o 100º byte e teria 40 bytes de tamanho

Possivelmente estamos trabalhando com arquivos binários não com arquivos ASCII, então a concatenação de 2 metades deve ser idêntica ao arquivo original!

(É possível com dd ?)

    
por PiNewbie 19.09.2017 / 20:17

2 respostas

10

Sim. Na página de manual do dd , você está procurando por algo como:

dd bs=1 count=60 if=_filename_1_ of=_filename_2_
dd bs=1 skip=60 count=40 if=_filename_1_ of=_filename_2_

onde _filename_n_ é substituído por um nome de arquivo real.

bs=1 significa que count e skip são contagens de bytes. skip é quantos para pular; count é quantos copiar. As contagens de bytes Editar começam de 0, não 1. Portanto, para começar no primeiro byte, use skip=0 (ou deixe skip não especificado).

Como uma função bash, você poderia usar:

# copy_nk(n, k, infile, outfile)
copy_nk() {
    dd bs=1 count="$1" skip="$2" ${3:+if="$3"} ${4:+of="$4"}
}

e depois chamá-lo como

copy_nk 60 0 infile.txt outfile.txt

(com k = 0 porque os números de bytes começam em zero).

Com o ${3:+...} , você pode deixar o arquivo de saída ou o arquivo de entrada. Por exemplo,

cat infile.txt | copy_nk 60 0 > outfile.txt
    
por 19.09.2017 / 20:55
5

Aqui está outra abordagem usando head e grupos de comandos bash:

{ head -c60 > /dev/null ; head -c40 > output.txt ; } < input.txt

O primeiro head aqui lê os primeiros 60 bytes do arquivo input.txt e os envia para o bloco de bits.

Como esses comandos head estão dentro do grupo de comandos, a posição do arquivo dentro de input.txt será preservada. Assim, o segundo head lerá os próximos 40 bytes (do byte 61 a 100 usando a indexação baseada em 1) e gravará no output.txt.

Na verdade, esse método pode ser generalizado para fornecer funcionalidade semelhante a split , mas com o benefício adicional de poder especificar o tamanho de cada arquivo de saída. Suponha que temos um arquivo de 100 bytes que queremos dividir em partes de tamanhos 7, 50, 23 e o restante. Nós poderíamos fazer:

{
    head -c7 > 7bytes.txt
    head -c50 > 50bytes.txt
    head -c23 > 23bytes.txt
    cat > remaining-bytes.txt
} < input.txt
    
por 19.09.2017 / 23:05