そこで、私はちょっとした愚かなミスを犯しました。ソースからデータを収集するプロセス中に、すべてを外部ディスクのルートにダンプしてしまいました。現在、そこには 60 万以上のファイル (合計 23 GB) があります。私が実行したいオプションは次のとおりです。
- 一定数のファイルをディスクからハードディスクに移動します。
- サブフォルダー (各サブフォルダーに 1000 個のファイル) を作成し、それらの間でファイルを分散します。
- 全体またはその一部 (たとえば 50,000 ファイル) を tar で圧縮し、ディスクに移動します。
しかし、何をやっても、永遠にかかるように思えます。誰か、これらのいずれかを実行する最適/最も効率的な方法について教えてくれませんか? よろしくお願いします。
答え1
以下のコマンドは、 というサブディレクトリを作成し、次に..という番号new
の付いたサブディレクトリを 50 個作成します。その後、現在のディレクトリから各ディレクトリに最大 1000 個のファイルを移動します。new
new/01
new/50
new/*
注1: 以下のいずれかの場合には動作しません。ファイル名改行 ( \n
) が含まれます。
注2: これには GNUxargs
と GNU が必要ですmv
。Linux を実行しているので、これらは標準です。
必要に応じて、数字 (50 と 1000) とベース ディレクトリを変更できます。
#! /bin/sh
BASEDIR='new'
SUBDIRS=50
FILECOUNT=1000
mkdir -p "$BASEDIR"
for i in $(seq -w 1 "$SUBDIRS") ; do
mkdir -p "$BASEDIR/$i"
# move maximum of $FILECOUNT files to new/$i
find . -maxdepth 1 -type f | head -n "$FILECOUNT" | xargs -d'\n' mv -t "$BASEDIR/$i"
done
移動したいファイルがすべて特定のパターンに一致する場合は、検索-name
または-regex
オプションを使用して選択できます。オプションは . の直後に追加します。たとえば、ファイル-type f
のみを移動したい場合は次のようにします。.txt
find . -maxdepth 1 -type f -name '*.txt' | head -n "$FILECOUNT" | xargs -d'\n' mv -t "$BASEDIR/$i"
非 GNU バージョンでは を使用できません。また、 オプションもmv -t
使用できませんが、 を使用して改行を NUL 文字に変換し、 に送ることができます。これも、ファイル名に が含まれていないファイルに対応します。 は POSIX 以外の の FreeBSD 拡張であるため、そのオプションを安全に削除できますが、操作の実行速度は大幅に低下します。xargs -d
tr '\n' '\0'
xargs -0r
\n
-R -1
xargs
mv
#! /bin/sh
BASEDIR='new'
SUBDIRS=50
FILECOUNT=1000
mkdir -p "$BASEDIR"
for i in $(seq -w 1 "$SUBDIRS") ; do
mkdir -p "$BASEDIR/$i"
# move maximum of $FILECOUNT files to new/$i
find . -maxdepth 1 -type f | head -n "$FILECOUNT" | tr '\n' '\0' | xargs -0r -R -1 -I % mv % "$BASEDIR/$i"
done