Qual é a maneira mais rápida de criar uma lista de diretórios especificados em um arquivo?

2

Eu tenho um arquivo de texto, "foo.txt", que especifica um diretório em cada linha:

data/bar/foo
data/bar/foo/chum
data/bar/chum/foo
...

Pode haver milhões de diretórios e subdiretórios Qual é a maneira mais rápida de criar todos os diretórios em massa, usando um comando de terminal?

Por mais rápido, quero dizer mais rápido para criar todos os diretórios. Como existem milhões de diretórios, há muitas operações de gravação.

Estou usando o Ubuntu 12.04.

EDIT: Tenha em mente, a lista pode não caber na memória, uma vez que existem milhões de linhas, cada um representando um diretório.

EDIT: Meu arquivo tem 4,5 milhões de linhas, cada uma representando um diretório, composto de caracteres alfanuméricos, o separador de caminho "/" e possivelmente "../"

Quando eu corri xargs -d '\n' mkdir -p < foo.txt depois de um tempo ele continuou imprimindo erros até que eu fizesse ctrl + c:

mkdir: não é possível criar o diretório '../myData/data/a/m/e/d': não há espaço no dispositivo

Mas a execução de df -h fornece a seguinte saída:

Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda        48G   20G   28G  42% /
devtmpfs        2.0G  4.0K  2.0G   1% /dev
none            401M  164K  401M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            2.0G     0  2.0G   0% /run/shm

free -m

 total       used       free     shared    buffers     cached
Mem:          4002       3743        258          0       2870         13
-/+ buffers/cache:        859       3143
Swap:          255         26        229

EDITAR: df -i

Filesystem      Inodes   IUsed  IFree IUse% Mounted on
/dev/xvda      2872640 1878464 994176   66% /
devtmpfs        512053    1388 510665    1% /dev
none            512347     775 511572    1% /run
none            512347       1 512346    1% /run/lock
none            512347       1 512346    1% /run/shm

df -T

Filesystem     Type     1K-blocks     Used Available Use% Mounted on
/dev/xvda      ext4      49315312 11447636  37350680  24% /
devtmpfs       devtmpfs   2048212        4   2048208   1% /dev
none           tmpfs       409880      164    409716   1% /run
none           tmpfs         5120        0      5120   0% /run/lock
none           tmpfs      2049388        0   2049388   0% /run/shm

EDIT: Eu aumentei o número de inodes, e reduzi a profundidade dos meus diretórios, e pareceu funcionar. Demorou 2m16seconds desta vez.

    
por Kaizer Sozay 15.12.2014 / 12:25

3 respostas

8

Com o GNU xargs :

xargs -d '\n' mkdir -p -- < foo.txt

xargs executará o menor número possível de mkdir de comandos.

Com sintaxe padrão:

(export LC_ALL=C
 sed 's/[[:blank:]"\'\'']/\&/g' < foo.txt | xargs mkdir -p --)

Quando não é eficiente, mkdir -p a/b/c tentará alguns mkdir("a") e possivelmente stat("a") e chdir("a") e o mesmo para "a/b" , mesmo se "a/b" já existisse.

Se o seu foo.txt tiver:

a
a/b
a/b/c

nessa ordem, ou seja, se para cada caminho tiver havido uma linha para cada um dos componentes do caminho antes, você poderá omitir o -p e será significativamente mais eficiente. Ou alternativamente:

perl -lne 'mkdir $_ or warn "$_: $!\n"' < foo.txt

O que evita invocar um (muitos) mkdir comando completamente.

    
por 15.12.2014 / 12:46
1

Sei que receberemos muitas respostas para essa pergunta. Mas ainda é possível EXPERIMENTAR essa :): D

while read -r line; do mkdir -p "$line" ; done < file.txt

    
por 15.12.2014 / 12:33
-1

Experimente este verso:

for i in $(cat foo.txt) ; do mkdir -p $i ; done

Isso criará o diretório / diretório-árvore no diretório de trabalho atual. Não a granel (como em todos os diretórios que estão sendo criados simultaneamente), mas a criação será feita um após o outro.

    
por 15.12.2014 / 12:33

Tags