I have a folder A with hundreds of thousands of files. I would like to move these files to new subfolders S_i, with, say, 100 files in each (the last folder may have less than 100 files)

In other words, if my folder A has:

file1
file2
...
file1000

I would later have:

S_1:    
    file_1
    ...
    file_100    
S_2:
    file_101
    ...
    file_200
...

Before I write a Zsh script manually to do this task (e.g. using variables to count files), I was wondering if there are any readily available tools (like split) that would facilitate this task.

up vote 4 down vote accepted

With zsh:

autoload zmv
zmv 'file_(<->)' 'S_$((1 + ($1 - 1) / 100))'

If the files are not numbered, but you just want to split that list:

n=0; zmv -Q 'file_*(n)' 'S_$((n++/100+1))'

(n) is to toggle numerical ordering for the list (and you need -Q for that globbing qualifier).

Those call one mv per file. You can make it a bit more efficient by making mv builtin (zmodload zsh/files), or you could do:

files=(file_*(nN))
for ((n=1; $#files; n++)) {
  mv -- $files[1,100] S_$n
  files[1,100]=()
}

The (nN) above are zsh globbing qualifiers which further qualify the glob. n is for numerical sorting, N is to turn on the nullglob option for that glob, that is for the glob to expand to an empty list when there is no match.

(with that one, you could even throw in a mkdir S_$n in case those directories didn't exist beforehand).

  • Thanks! What does *(nN) do in the first line of the last example? – Amelio Vazquez-Reina Feb 26 '13 at 0:27
  • @user27915816, I've updated the answer. – Stéphane Chazelas Feb 26 '13 at 7:18

If the filenames don't contain spaces:

i=1;while read l;do mkdir $i;mv $l $((i++));done< <(ls|xargs -n100)

Using parallel:

ls|parallel -n100 mkdir {#}\;mv {} {#}

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.