各行にディレクトリを指定するテキストファイル「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
xargs
mkdir
できるだけ少ない数のコマンドを実行してください。
標準構文を使用してください。
(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
これにより、現在の作業ディレクトリにディレクトリ/ディレクトリツリーが作成されます。一括作成ではなく(すべてのディレクトリを同時に作成するなど)、順番に作成します。