ファイルで指定されたディレクトリのリストを作成する最速の方法は何ですか?

ファイルで指定されたディレクトリのリストを作成する最速の方法は何ですか?

各行にディレクトリを指定するテキストファイル「foo.txt」があります。

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

潜在的に数百万のディレクトリとサブディレクトリがあります。ターミナルコマンドを使用してすべてのディレクトリとサブディレクトリを一括生成する最速の方法は何ですか?

最も速いということは、すべてのディレクトリを作成することが最も速いことを意味します。何百万ものディレクトリがあるので、書き込み操作もたくさんあります。

Ubuntu 12.04を使用しています。

編集:それぞれのディレクトリを表す数百万行があるため、このリストはメモリに収まらない可能性があります。

編集:私のファイルには450万行があります。各行はディレクトリを表し、英数字、パス区切り文字「/」、「../」で構成されます。

xargs -d '\n' mkdir -p < foo.txtしばらく実行すると、Ctrl + Cを実行するまで印刷エラーが発生し続けます。

mkdir: '../myData/data/a/m/e/d' ディレクトリを作成できません: デバイスに空き容量がありません

ただし、実行すると、df -h次のような結果が表示されます。

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

自由-m

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

編集: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

編集:inodeの数を増やし、ディレクトリの深さを減らしましたが、これはうまくいくようです。今回は2分16秒かかりました。

答え1

GNUの使用xargs:

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

xargsmkdirできるだけ少ない数のコマンドを実行してください。

標準構文を使用してください。

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

非効率性は、事前に存在しても一部可能であり、同じ操作がmkdir -p a/b/c試みられることです。mkdir("a")stat("a")chdir("a")"a/b""a/b"

あなたがfoo.txt持っているなら:

a
a/b
a/b/c

この順序で、つまり各パスに対して前の各パスコンポーネントの行がある場合は、それらを省略することができ、はるかに-p効率的です。または:

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

これにより、(多くの)mkdirコマンドが完全に呼び出されるのを防ぎます。

答え2

私たちはこの質問に多くの答えを得ることができることを知っています。しかし、あなたはまだできます。努力するこれ:) :D

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

答え3

次の1行を試してください。

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

これにより、現在の作業ディレクトリにディレクトリ/ディレクトリツリーが作成されます。一括作成ではなく(すべてのディレクトリを同時に作成するなど)、順番に作成します。

関連情報