Tenho 10k + arquivos, totalizando mais de 20GB, que preciso concatenar em um arquivo.
Existe uma maneira mais rápida do que
cat input_file* >> out
?
A maneira preferida seria um comando bash, o Python também é aceitável, se não consideravelmente mais lento.
bash
shell-script
files
cat
fsperrle
fonte
fonte
find
não classifica os arquivos da mesma forma que um shell glob.out
estiver localizado em outro disco.Respostas:
Não, gato é certamente a melhor maneira de fazer isso. Por que usar python quando já existe um programa escrito em C para esse fim? No entanto, você pode querer considerar o uso
xargs
, caso o comprimento da linha de comando excedaARG_MAX
e você precise de mais de umcat
. Usando as ferramentas GNU, isso é equivalente ao que você já possui:fonte
find
é canalizadasort
. Sem isso, os arquivos seriam listados em uma ordem arbitrária (definida pelo sistema de arquivos, que poderia ser a ordem de criação de arquivos).bash
glob. Caso contrário, não vejo casos em quexargs
oucat
não se comportariam conforme o esperado.xargs
ligará ocat
quanto for necessário para evitar um erro E2BIG do execve (2).Alocar o espaço para o arquivo de saída primeiro pode melhorar a velocidade geral, pois o sistema não precisará atualizar a alocação para cada gravação.
Por exemplo, se no Linux:
Outro benefício é que, se não houver espaço livre suficiente, a cópia não será tentada.
Se ativado
btrfs
, você poderácopy --reflink=always
o primeiro arquivo (que não implica cópia de dados e, portanto, seria quase instantâneo) e anexar o restante. Se houver 10000 arquivos, isso provavelmente não fará muita diferença, a menos que o primeiro arquivo seja muito grande.Existe uma API para generalizar isso para copiar novamente todos os arquivos (o
BTRFS_IOC_CLONE_RANGE
ioctl
), mas não consegui encontrar nenhum utilitário que exponha essa API; portanto, você deve fazê-lo em C (python
ou em outros idiomas, desde que possam chamarioctl
s arbitrários ) .Se os arquivos de origem forem esparsos ou tiverem grandes seqüências de caracteres NUL, você poderá criar um arquivo de saída esparso (economizando tempo e espaço em disco) com (nos sistemas GNU):
fonte
>
nem>>
, mas1<>
como eu disse para escrever no arquivo.<>
é o operador padrão de redirecionamento de leitura e gravação Bourne / POSIX. Consulte o manual do shell ou a especificação POSIX para obter detalhes. O padrãofd
é0
para o<>
operador (<>
é abreviado para0<>
, como<
é abreviado0<
e>
abreviado1>
), portanto, você precisa1
redirecionar explicitamente o stdout. Aqui, não é muito o que precisamos ler + escrever (O_RDWR
), mas não queremosO_TRUNC
(como em>
) o que desalocaria o que acabamos de alocar.dd
ou via leitura.fallocate
que negaremos a sobrecarga do extrafind
, mesmo que seja mais rápido na segunda vez.btrfs
certamente abre algumas possibilidades interessantes.