Break down a large folder into multiple subfolders by sequential names [duplicate]
This question already has an answer here:
How can I move files into subdirectories by count? [duplicate]
2 answers
I have a folder with 20000 files in it. I need to split it into subfolders with increasing directory name (dir_1, dir_2....) with each folder having 500 files each in such a way that for example if files are from file_1.png to file_20000, the first folder should contain first 500 files i.e., file_1 to file 500 and immediate folder should contain files in a continued manner i.e, file_501 to file_1000 and so on.
shell-script
marked as duplicate by don_crissti, Jeff Schaller, Stephen Harris, Archemar, Mr Shunz Jan 8 at 8:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
How can I move files into subdirectories by count? [duplicate]
2 answers
I have a folder with 20000 files in it. I need to split it into subfolders with increasing directory name (dir_1, dir_2....) with each folder having 500 files each in such a way that for example if files are from file_1.png to file_20000, the first folder should contain first 500 files i.e., file_1 to file 500 and immediate folder should contain files in a continued manner i.e, file_501 to file_1000 and so on.
shell-script
marked as duplicate by don_crissti, Jeff Schaller, Stephen Harris, Archemar, Mr Shunz Jan 8 at 8:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
5
please please do not post images of text. Or, if you must, at least don't post such sparse images, and make them more helpful in the context of the question.
– DopeGhoti
Jan 7 at 18:15
add a comment |
This question already has an answer here:
How can I move files into subdirectories by count? [duplicate]
2 answers
I have a folder with 20000 files in it. I need to split it into subfolders with increasing directory name (dir_1, dir_2....) with each folder having 500 files each in such a way that for example if files are from file_1.png to file_20000, the first folder should contain first 500 files i.e., file_1 to file 500 and immediate folder should contain files in a continued manner i.e, file_501 to file_1000 and so on.
shell-script
This question already has an answer here:
How can I move files into subdirectories by count? [duplicate]
2 answers
I have a folder with 20000 files in it. I need to split it into subfolders with increasing directory name (dir_1, dir_2....) with each folder having 500 files each in such a way that for example if files are from file_1.png to file_20000, the first folder should contain first 500 files i.e., file_1 to file 500 and immediate folder should contain files in a continued manner i.e, file_501 to file_1000 and so on.
This question already has an answer here:
How can I move files into subdirectories by count? [duplicate]
2 answers
shell-script
shell-script
edited Jan 8 at 0:08
Rui F Ribeiro
39.5k1479132
39.5k1479132
asked Jan 7 at 17:57
Praveen KumarPraveen Kumar
313
313
marked as duplicate by don_crissti, Jeff Schaller, Stephen Harris, Archemar, Mr Shunz Jan 8 at 8:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by don_crissti, Jeff Schaller, Stephen Harris, Archemar, Mr Shunz Jan 8 at 8:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
5
please please do not post images of text. Or, if you must, at least don't post such sparse images, and make them more helpful in the context of the question.
– DopeGhoti
Jan 7 at 18:15
add a comment |
5
please please do not post images of text. Or, if you must, at least don't post such sparse images, and make them more helpful in the context of the question.
– DopeGhoti
Jan 7 at 18:15
5
5
please please do not post images of text. Or, if you must, at least don't post such sparse images, and make them more helpful in the context of the question.
– DopeGhoti
Jan 7 at 18:15
please please do not post images of text. Or, if you must, at least don't post such sparse images, and make them more helpful in the context of the question.
– DopeGhoti
Jan 7 at 18:15
add a comment |
3 Answers
3
active
oldest
votes
#!/bin/sh
files_per_dir=500
set -- file_*
printf 'There are %d filesn' "$#"
printf 'Putting %d files in each new directoryn' "$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 %sn' "$dir"
# mkdir "$dir"
fi
n=$(( n + 1 ))
printf 'Moving %s to %sn' "$filename" "$dir"
# mv -i -- "$filename" "$dir"
done
The above would put 500 files into each directory (the actual commands that changes things have been commented out for safety). The filenames are assumed to match file_*
and each new directory will be called dir_N
where N
is a positive integer.
If you want to move the files based on their numerical names (the above sorts the files in lexicographical order), then use
printf 'Moving %s to %sn' "file_$n" "$dir"
# mv -i -- "file_$n" "$dir"
instead (i.e. replace the corresponding two lines in the first script with these, in this order).
Shortened version:
#!/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
add a comment |
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
add a comment |
Something simple along the lines of:
#!/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
Not tested, so you might put an echo
in front of the mv "$file" dir_$j
to see if it does what you want. Anyway it will give you an idea of how to do what you want.
Yes it works. That's why thetypeset -i
is there. Yes, I use string comparison, but that also works. Would you prefer I put#!/bin/sh
as first line?
– Ljm Dullaart
Jan 7 at 18:23
1
Using the string comparison operator fortest
(=
) for numerical comparisons is bad practice. Use the numerical comparisons (-eq
) when performing numerical equality tests. Using the wildard (for file in *
) may catch more files than the specifiedfile_{1..20000}.png
.
– DopeGhoti
Jan 7 at 18:32
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
#!/bin/sh
files_per_dir=500
set -- file_*
printf 'There are %d filesn' "$#"
printf 'Putting %d files in each new directoryn' "$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 %sn' "$dir"
# mkdir "$dir"
fi
n=$(( n + 1 ))
printf 'Moving %s to %sn' "$filename" "$dir"
# mv -i -- "$filename" "$dir"
done
The above would put 500 files into each directory (the actual commands that changes things have been commented out for safety). The filenames are assumed to match file_*
and each new directory will be called dir_N
where N
is a positive integer.
If you want to move the files based on their numerical names (the above sorts the files in lexicographical order), then use
printf 'Moving %s to %sn' "file_$n" "$dir"
# mv -i -- "file_$n" "$dir"
instead (i.e. replace the corresponding two lines in the first script with these, in this order).
Shortened version:
#!/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
add a comment |
#!/bin/sh
files_per_dir=500
set -- file_*
printf 'There are %d filesn' "$#"
printf 'Putting %d files in each new directoryn' "$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 %sn' "$dir"
# mkdir "$dir"
fi
n=$(( n + 1 ))
printf 'Moving %s to %sn' "$filename" "$dir"
# mv -i -- "$filename" "$dir"
done
The above would put 500 files into each directory (the actual commands that changes things have been commented out for safety). The filenames are assumed to match file_*
and each new directory will be called dir_N
where N
is a positive integer.
If you want to move the files based on their numerical names (the above sorts the files in lexicographical order), then use
printf 'Moving %s to %sn' "file_$n" "$dir"
# mv -i -- "file_$n" "$dir"
instead (i.e. replace the corresponding two lines in the first script with these, in this order).
Shortened version:
#!/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
add a comment |
#!/bin/sh
files_per_dir=500
set -- file_*
printf 'There are %d filesn' "$#"
printf 'Putting %d files in each new directoryn' "$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 %sn' "$dir"
# mkdir "$dir"
fi
n=$(( n + 1 ))
printf 'Moving %s to %sn' "$filename" "$dir"
# mv -i -- "$filename" "$dir"
done
The above would put 500 files into each directory (the actual commands that changes things have been commented out for safety). The filenames are assumed to match file_*
and each new directory will be called dir_N
where N
is a positive integer.
If you want to move the files based on their numerical names (the above sorts the files in lexicographical order), then use
printf 'Moving %s to %sn' "file_$n" "$dir"
# mv -i -- "file_$n" "$dir"
instead (i.e. replace the corresponding two lines in the first script with these, in this order).
Shortened version:
#!/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
#!/bin/sh
files_per_dir=500
set -- file_*
printf 'There are %d filesn' "$#"
printf 'Putting %d files in each new directoryn' "$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 %sn' "$dir"
# mkdir "$dir"
fi
n=$(( n + 1 ))
printf 'Moving %s to %sn' "$filename" "$dir"
# mv -i -- "$filename" "$dir"
done
The above would put 500 files into each directory (the actual commands that changes things have been commented out for safety). The filenames are assumed to match file_*
and each new directory will be called dir_N
where N
is a positive integer.
If you want to move the files based on their numerical names (the above sorts the files in lexicographical order), then use
printf 'Moving %s to %sn' "file_$n" "$dir"
# mv -i -- "file_$n" "$dir"
instead (i.e. replace the corresponding two lines in the first script with these, in this order).
Shortened version:
#!/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
edited Jan 7 at 20:04
answered Jan 7 at 18:19
KusalanandaKusalananda
124k16234386
124k16234386
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
edited Jan 7 at 18:33
answered Jan 7 at 18:14
DopeGhotiDopeGhoti
43.9k55582
43.9k55582
add a comment |
add a comment |
Something simple along the lines of:
#!/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
Not tested, so you might put an echo
in front of the mv "$file" dir_$j
to see if it does what you want. Anyway it will give you an idea of how to do what you want.
Yes it works. That's why thetypeset -i
is there. Yes, I use string comparison, but that also works. Would you prefer I put#!/bin/sh
as first line?
– Ljm Dullaart
Jan 7 at 18:23
1
Using the string comparison operator fortest
(=
) for numerical comparisons is bad practice. Use the numerical comparisons (-eq
) when performing numerical equality tests. Using the wildard (for file in *
) may catch more files than the specifiedfile_{1..20000}.png
.
– DopeGhoti
Jan 7 at 18:32
add a comment |
Something simple along the lines of:
#!/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
Not tested, so you might put an echo
in front of the mv "$file" dir_$j
to see if it does what you want. Anyway it will give you an idea of how to do what you want.
Yes it works. That's why thetypeset -i
is there. Yes, I use string comparison, but that also works. Would you prefer I put#!/bin/sh
as first line?
– Ljm Dullaart
Jan 7 at 18:23
1
Using the string comparison operator fortest
(=
) for numerical comparisons is bad practice. Use the numerical comparisons (-eq
) when performing numerical equality tests. Using the wildard (for file in *
) may catch more files than the specifiedfile_{1..20000}.png
.
– DopeGhoti
Jan 7 at 18:32
add a comment |
Something simple along the lines of:
#!/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
Not tested, so you might put an echo
in front of the mv "$file" dir_$j
to see if it does what you want. Anyway it will give you an idea of how to do what you want.
Something simple along the lines of:
#!/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
Not tested, so you might put an echo
in front of the mv "$file" dir_$j
to see if it does what you want. Anyway it will give you an idea of how to do what you want.
answered Jan 7 at 18:15
Ljm DullaartLjm Dullaart
60817
60817
Yes it works. That's why thetypeset -i
is there. Yes, I use string comparison, but that also works. Would you prefer I put#!/bin/sh
as first line?
– Ljm Dullaart
Jan 7 at 18:23
1
Using the string comparison operator fortest
(=
) for numerical comparisons is bad practice. Use the numerical comparisons (-eq
) when performing numerical equality tests. Using the wildard (for file in *
) may catch more files than the specifiedfile_{1..20000}.png
.
– DopeGhoti
Jan 7 at 18:32
add a comment |
Yes it works. That's why thetypeset -i
is there. Yes, I use string comparison, but that also works. Would you prefer I put#!/bin/sh
as first line?
– Ljm Dullaart
Jan 7 at 18:23
1
Using the string comparison operator fortest
(=
) for numerical comparisons is bad practice. Use the numerical comparisons (-eq
) when performing numerical equality tests. Using the wildard (for file in *
) may catch more files than the specifiedfile_{1..20000}.png
.
– DopeGhoti
Jan 7 at 18:32
Yes it works. That's why the
typeset -i
is there. Yes, I use string comparison, but that also works. Would you prefer I put #!/bin/sh
as first line?– Ljm Dullaart
Jan 7 at 18:23
Yes it works. That's why the
typeset -i
is there. Yes, I use string comparison, but that also works. Would you prefer I put #!/bin/sh
as first line?– Ljm Dullaart
Jan 7 at 18:23
1
1
Using the string comparison operator for
test
(=
) for numerical comparisons is bad practice. Use the numerical comparisons (-eq
) when performing numerical equality tests. Using the wildard (for file in *
) may catch more files than the specified file_{1..20000}.png
.– DopeGhoti
Jan 7 at 18:32
Using the string comparison operator for
test
(=
) for numerical comparisons is bad practice. Use the numerical comparisons (-eq
) when performing numerical equality tests. Using the wildard (for file in *
) may catch more files than the specified file_{1..20000}.png
.– DopeGhoti
Jan 7 at 18:32
add a comment |
5
please please do not post images of text. Or, if you must, at least don't post such sparse images, and make them more helpful in the context of the question.
– DopeGhoti
Jan 7 at 18:15