Em:
cat */* > bigtextfile.txt
O shell expandirá */*
para a lista classificada de arquivos correspondentes (não ocultos) e executará cat
com esses caminhos de arquivos como argumentos.
cat
abrirá cada arquivo por vez e gravará em seu stdout o que ele lê no arquivo. cat
não armazenará mais de um buffer cheio de dados (algo como alguns bytes de quilo) por vez na memória.
Um problema que você pode encontrar é que a lista de argumentos para cat
é tão grande que atinge o limite do tamanho dos argumentos da chamada de sistema execve()
. Então, você pode precisar dividir essa lista de arquivos e executar cat
várias vezes.
Você pode usar xargs
para isso (aqui com GNU ou BSD xargs
para as opções não-padrão -r
e -0
):
printf '%sfind . -mindepth 2 -maxdepth 2 -type f -exec cat {} + > big-file.txt
' */* | xargs -r0 cat -- > big-file.txt
(porque printf
é construído no shell, ele não passa pela chamada do sistema execve
, portanto, não pelo seu limite).
Ou use find
na lista de arquivos e execute quantos comandos forem necessários:
find . -path './*/*' -prune -type f -exec cat {} + > big-file.txt
Ou portavelmente:
ulimit -s unlimited
cat -- */* > big-file.txt
(lembre-se que ao contrário de */*
, ele incluirá arquivos ocultos (e arquivos em diretórios ocultos), e não procurará arquivos em links simbólicos para os diretórios, e a lista de arquivos não será ordenada).
Se em uma versão recente do Linux, você pode aumentar o limite do tamanho dos argumentos:
autoload zargs
zargs -- */* -- cat > big-file.txt
Com zsh
, você também pode usar zargs
:
command -x cat -- */* > big-file.txt
Com ksh93
, você pode usar command -x
:
command /opt/ast/bin/cat -- */* > big-file.txt
Todos fazem a mesma coisa, dividem a lista de arquivos e executam quantos comandos cat
, conforme necessário.
Com ksh93
novamente, você pode contornar o limite execve()
usando o comando cat
incorporado:
cat */* > bigtextfile.txt