ファイルを複数のフォルダに移動する[閉じる]

ファイルを複数のフォルダに移動する[閉じる]

この機能を検索してみると回答がたくさんありますが、私に合った機能が見つかりません。

約30,000個のファイルを含むフォルダがあり、これらのファイルを別のフォルダに移動するには、ターミナルコマンドまたはbashスクリプトが必要です。各フォルダには約3000個のファイルがあります。一部のファイル名にはアンダースコア、スペース、ハイフンが含まれているため、このコマンドを使用すると、アンダースコア、スペース、ハイフンなしでファイルとファイルを移動できます。ファイルは.jpgですが、後で別の形式と数で使用する必要がある場合に備えて、すべてのファイルタイプとファイル数に合わせてカスタマイズできるコマンドが必要です。

修正する:

必要なタスクを実行するbashスクリプトが見つかりました。フォルダ内のファイルをサブフォルダに移動します。あらゆる種類のファイルで動作します。数字「3001」は、各サブフォルダに移動するファイルの数を示す。この番号は変更されることがあります。したがって、20,000個のファイルを含むフォルダがあり、20,000個のファイルを500個のバッチに分割してサブフォルダに移動するには、「3001」を「500」に置き換えます。特定のファイル形式のみを移動するようにスクリプトを変更することもできます。たとえば、.jpgファイルのみを移動するには、「for file in *」を「for jpg_file in *.jpg」に変更します。また、「$file」を「$jpg_file」に変更します。

#!/bin/bash

c=1; d=1; mkdir -p dir_${d}

for file in *
do
        if [ $c -eq 3001 ]
        then
                d=$(( d + 1 )); c=0; mkdir -p dir_${d}
        fi
        mv "$file" dir_${d}/
        c=$(( c + 1 ))
done

答え1

私はすべてのスクリプトを試しましたが、何らかの理由で機能しなかったか、部分的にのみ機能しました。私このbashスクリプトが見つかりました。そして、.xmlファイルの代わりに.jpgファイルを見つけるように調整します。

#!/bin/bash

c=1; d=1; mkdir -p dir_${d}

for jpg_file in *.jpg
do
        if [ $c -eq 501 ]
        then
                d=$(( d + 1 )); c=0; mkdir -p dir_${d}
        fi
        mv "$jpg_file" dir_${d}/
        c=$(( c + 1 ))
done

それはうまく動作し、迅速に動作します。今私の唯一の問題は、".jpg"だけでなく、すべてのファイルをフォルダに移動することです。また、大文字と小文字を区別し、「.JPG」は移動されません。ファイルまたは少なくとも画像ファイルを移動するように調整する方法についてのアイデアはありますか?

答え2

どうですか?

for letter in {A..Z}; do
   dir=/path/to/sorted/directories/$letter
   mkdir $dir
   mv "${letter}*.jpg" $dir/
done

もちろん、小文字を使用するのと同じループがあります{a..z}。ただし、この場合は別の小文字ディレクトリを作成したくありません。すると、動く線は次のようになります。

mv "${letter}*.jpg" ${dir^^}/

変数を生成するための大文字バージョンには${var^^}Bash 4.0が必要です。

編集:欠落している引用符を修正しました。この点を指摘してくれたG-manに感謝します。

答え3

私の考えには次のようになります。

#!/bin/bash
shopt -s nullglob
for i in <directory>; do
    mv *.jpg "$dir"
done

これにより、すべてのjpegが設定する必要がある$dirに移動するか、ディレクトリ名を持つ配列を作成する必要があります。*.jpg別の形式に切り替えることで、このコードを簡単にカスタマイズできます。ニーズに合わせてカスタマイズするには、このコードスニペットを調整する必要があります。

更新この機能を作成するには、次のことを試してください。

#!/bin/bash
echo "Enter Directory: ";
read dir
mkdir $dir

moveFiles(){
    arg1=$1    
    counter=0;
    while[$counter -ne 3000]; do
          mv <source> *.jpg "$dir"
          counter++;
          if[$counter -e 3000];
          then
               exit;
          fi
     done
}   
moveFiles "$dir"
exit

繰り返しますが、このコードを調整する必要があるかもしれません。これは単なる例です。

答え4

あなたが持っていると仮定ディレクトリあなたは移動したいファイルソース:

あなたはそれを使用することができます:

$ mv <source folder/*.jpg <destination folder/>

編集する:

次のスクリプトは、定義された検索基準に一致するすべてのファイルを見つけ、file_screenループwhileを実行して選択したファイルを移動します。

モジュロ基準に基づいて新しいディレクトリが作成されます。loop iteration mod files_in_each.modが0を返すと、新しいディレクトリが作成され、ファイルがそのディレクトリに移動されます。

操作中に調整する必要があるパラメータ:

files_in_each=3000  # controls how many files are placed in each directory
directory_to_move="/home/shadowe/test1/test2" # where are the files located
file_screen="jpg"   # only move files that match this criteria

必要に応じて調整してください。

#!/bin/bash

# basic definitions and calculations
files_in_each=3000
directory_to_move="/home/shadowe/test1/test2"
file_screen="jpg"
folders_created=0
i=0

# while loop through all of the files that match screening criteria
find $directory_to_move/* -maxdepth 1 -type f -name "*${file_screen}" -print0 | sort -n | while IFS= read -r -d '' file; 
do
    # modulo control for creating directories every files in each completion
    create_dir=`expr $i % $files_in_each`
    if [ $create_dir -eq "0" ]
    then
            new_folder=folder$folders_created
            mkdir $new_folder
            echo "created new folder: " $new_folder
            folders_created=$[$folders_created+1]
    fi
    mv "$file" $new_folder
    i=$[$i+1]
done

小さなサンプルを実行した後の結果:

$ ls test2/
not a picture.txt
$ ls folder0/
one.jpg      one*two.jpg       picture 1.jpg  two-one.jpg
one-two.jpg  picture 1111.jpg  picture *.jpg  two three.jpg

大規模なサンプル結果:

$ ls folder0 | wc -l
3000
$ ls folder1 | wc -l
2008
$ ls test2 | wc -l
7501
$ ls test2/ | grep "jpg"
$

テストファイルを生成するスクリプト:

#!/bin/bash

mkdir test2
touch test2/one.jpg
touch test2/'one-two.jpg'
touch test2/'one*two.jpg'
touch test2/'two-one.jpg'
touch test2/'two three.jpg'
touch test2/'picture 1.jpg'
touch test2/'picture *.jpg'
touch test2/'picture 1111.jpg'
touch test2/'not a picture.txt'
#for large test sample uncomment below
#for i in `seq 1 7500`; do touch test2/test$i.txt; done
#for j in `seq 1 5000`; do touch test2/picture$j.jpg; done

関連情報