Based on my old script with some modification (just changed the N value and variable names :):
Grouping each N files in separate directories
##grouping each N files in separate directories
echo 1 > dircount;
find source -type f -name 'filterFileName' -print0 | sort -z --version-sort | \
xargs -0n2500 bash -c 'read TARGET <dircount; \
echo mkdir -p "subdir$TARGET"; \
echo mv -t "subdir$TARGET" "$@"; \
expr $TARGET + 1 >dircount' grouping
-print0
prints the filenames separated by the NUL (\0
) character. It's the safest way to pass filenames as output to other commands.
sort
with -z
looks for nul-delimited input, and the --version-sort
allows to safely sort variable length numbers, so that filename2.xyz comes before fileName3.xyz
xargs
with -n2500
limit the number of arguments applied to each command (in this case 2500 arguments). The -0
is for nul-delimited input.
Note: Don't forget that you are running the script in test case, so clear the echo
command next to the related lines to performing to run actual script.
Also there are two another scripts which are not as fast as above one:
groupFiles=0
TARGET=1
for file in `ls -v /path/to/source/filterFileName` ; do
mkdir -p "subdir$TARGET" && mv "$file" "subdir$TARGET"
[[ ++groupFiles -eq 2500 ]] && groupFiles=0 && ((TARGET++))
done
ls -v
command sorts the files as natural sort of (version) numbers.
You can parse the ls
command if files name has no whitespace, new-line, etc.
mkdir -p "subdir$TARGET"
crates the directory based on TARGET
variable.
mv "$file" "subdir$TARGET"
moves the file to directory which TARGET
specifies.
Reset the groupFiles=0
to zero when 2500 files has been moved ([[ ++groupFiles -eq 2500 ]]
) and increment to TARGET
value.
Note that change /path/to/source/
to your actual source directory.
If you don't want to parse the ls
command due files name including spaces, new-lines and etc, here is another option to do:
groupFiles=0
TARGET=1
find /path/to/source/ -type f -name 'filterFileName' -print0 | \
sort -z --version-sort | while IFS= read -d '' -r file; do \
mkdir -p "subdir$TARGET" && mv "$file" "subdir$TARGET" ;
[[ ++groupFiles-eq 7 ]] && groupFiles=0 && ((TARGET++));
done