あるディレクトリに約9000個のファイルがあり、残りのファイルは無視してファイル名順に100個のディレクトリの90個のファイルに転送しようとします。存在するファイル名Xからファイル名Yに複数のファイルをコピーしますか?、ガレブに書かれたコメント:
オブジェクトがバッチ処理する場合、より簡単な方法があります!
ls | xargs -iX -n20 cp X target_folder/
cpはすべて完了するまで20グループのファイルに対して実行されます。
それでは、xargsの使用に基づいてtarget_folderを切り替えて新しいフォルダを作成し、コマンドを100回繰り返すにはどうすればよいですか?
答え1
でbash
次のコードを試してください。
#!/bin/bash
c=0
for f; do
if ! ((c % 100)); then
folder=folder_$(printf "%03d\n" $c)
mkdir -p $folder
fi
[[ -d "$f" ]] || mv "$f" "$folder"
((c++))
done
次のようにスクリプトを実行します。
./script.bash *
答え2
このコマンドは、実行したい操作に近いようではありません。xargs
役に立つかもしれませんが、ファイル名にスペースや引用符が含まれていない場合は、使用するのが面倒です。これは、新しく作成されたサブディレクトリ(ディレクトリあたり90個)にファイルを渡すシェルループです。
set -- *
# Set args to "$1" "$2" ... "$90"
i=1 args=
while [ $i -le 90 ]; do
slice="$slice \"\${$i}\""
i=$((i+1))
done
# Move files 90 at a time
i=0
while [ $# -ge 90 ]; do
mkdir part$i
eval "mv $slice part$i"
shift 90
done
# 0 to 89 files remain in the current directory
答え3
parallel
複数のコマンド実行をサポートします。ここで、\;
および{#}
はシーケンス番号です。
ls|parallel -n90 mkdir {#}\;mv {} {#}
または、ファイル名にスペース、引用符、またはバックスラッシュが含まれていない場合:
i=1;while read l;do mkdir $i;mv $l $((i++));done< <(ls|xargs -n90)