シーケンシャル名に基づいて、大規模フォルダを複数のサブフォルダに分割します。

シーケンシャル名に基づいて、大規模フォルダを複数のサブフォルダに分割します。

20,000個のファイルを含むフォルダがあります。ディレクトリ名が増えるサブフォルダ(dir_1、dir_2...)に分割する必要があります。各フォルダには500個のファイルがあります。たとえば、ファイルがfile_1.pngからfile_20000に移動した場合、最初のフォルダに最初の500個のファイルを含める必要があります。 file_1からfile_500まで、Directフォルダにはfile_501からfile_1000までのファイルを連続して含める必要があります。 ここに画像の説明を入力してください。

答え1

#!/bin/sh

files_per_dir=500

set -- file_*

printf 'There are %d files\n' "$#"
printf 'Putting %d files in each new directory\n' "$files_per_dir"

N=0 # directory counter
n=0 # file counter

for filename do

    if [ "$(( n % files_per_dir ))" -eq 0 ]; then
        N=$(( N + 1 ))
        dir="dir_$N"
        printf 'Creating directory %s\n' "$dir"
        # mkdir "$dir"
    fi

    n=$(( n + 1 ))

    printf 'Moving %s to %s\n' "$filename" "$dir"
    # mv -i -- "$filename" "$dir"

done

上記のコードは各ディレクトリに500個のファイルを置きます(内容を変更する実際のコマンドは安全のためにコメントされています)。ファイル名は一致すると見なされ、正の整数である新しいfile_*ディレクトリごとに呼び出されます。dir_NN

数値名に基づいてファイルを移動するには(上記ではファイルをアルファベット順に並べ替えます)、次のようにします。

printf 'Moving %s to %s\n' "file_$n" "$dir"
# mv -i -- "file_$n" "$dir"

代わりに(つまり、最初のスクリプトの2行をこの順序で置き換えます)。


短縮バージョン:

#!/bin/sh

files_per_dir=500

set -- file_*

n=0

for filename do
    n=$(( n + 1 ))

    N=$(( (n/files_per_dir) + 1 ))
    [ ! -d "dir_$N" ] && mkdir "dir_$N"

    # mv -i -- "$filename" "dir_$N"
    # or...
    # mv -i -- "file_$n" "dir_$N"
done

答え2

cd lotsafiles
for i in {1..20000}; do
  dirnum="$(((i/500)+1))"
  mkdir -p "dir_${dirnum}" # using -p allows this to be less noisy on repeat runs
  mv "file${i}.png" "dir_${dirnum}"/
done

答え3

簡単なことは次のように行われます。

#!/bin/bash
typeset -i i
typeset -i j
typeset -i k

i=0
j=0
k=0
mkdir dir_$j
for file in * ; do
   i=$i+1
   k=$k+1
   if [ $i = 500 ] ; then
       j=$j+1
       i=0
       mkdir  dir_$j
   fi
   mv "$file" dir_$j/file_$k
done

テストされていないため、echo前に追加してmv "$file" dir_$j 要件を満たしていることを確認できます。とにかく、それはあなたが望むことをどうするかについてのアイデアを与えます。

関連情報