Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

There are too many files [*] in a certain folder. I'd like to move some of them into a sub-folder. How can I:

  • move first 3000 files or folders into another folder, or
  • move files older than 3 months into another folder?


share|improve this question
up vote 1 down vote accepted

By far the easiest way is to use zsh. To move the first 3000 files in the current directory into /other/directory:

mv *([1,3000]) /other/directory

If you've created a few subdirectories that you want to exclude from that command:

setopt extended_glob
mv *([1,3000])~(exclude-me|exclude-me-too) /other/directory

To move files older than 3 months (the first m is for “modification time”, and the second m means months; fractional parts are ignored, so +2 means ≥3):

mv *(mm+2) /other/directory

If you'd rather use complicated commands than start a different shell, these are still reasonable one-liners with GNU find:

find -mindepth 1 -maxdepth 1 -print0 | head -n 3000 | xargs -0 -i mv {} /other/directory
find -mindepth 1 -maxdepth 1 -mtime +91 -print0 | xargs -0 -i mv {} /other/directory
share|improve this answer

The find command should be of help with some minor scripting over it.

Some references,

  1. A Unix/Linux "find" Command Tutorial
  2. Linux find command examples
  3. Command Line Interface Ninja Howto

Figure out how you want to re-distribute the files and directories to write your command line or short-script based on these examples.

share|improve this answer

A script like this should work to move the first NUMBER_OF_FILES files to SUBDIRECTORY:


find . -type f -maxdepth 1 | sort > /tmp/$$  
exec 4</tmp/$$  
while read FILENAME <&4  
NUM=`expr $NUM + 1`  
if [ $NUM -le $NUMBER_OF_FILES ]  
rm /tmp/$$ 

Something like this for modified 90 days ago or more:


find . -type f -maxdepth 1 -mtime +$NUMBER_OF_DAYS | sort > /tmp/$$  
exec 4</tmp/$$  
while read FILENAME <&4  
rm /tmp/$$
share|improve this answer
The temporary file and extra file descriptor are unnecessary if you just pipe the find into the while read. Also, variables containing filenames should be quoted and code within loops and if statements should be indented (I code-formatted your code for you). – Dennis Williamson Oct 12 '10 at 15:17
Also, hardcoded parameters are bad. – reinierpost Oct 12 '10 at 15:40
And so are tempfiles. – reinierpost Oct 12 '10 at 15:41
And the sort is superfluous. – reinierpost Oct 12 '10 at 15:42
Thanks for the feedback on the script. In this case, the output of find could be piped to the while. However, I've been burned with this when using some shells that spawn a sub-shell when piping commands together, causing any changes to variables within the loop to be lost when it exits. For instance, if a count of files was desired, and a counter variable incremented within the loop using the piping technique, that variable would revert to its original value after the loop ends, and lose the count value. The tempfile technique above avoids that. – E Brown Nov 18 '10 at 16:03

How I would modify Dennis Williamson's answer:

find . -maxdepth 1 -type f -mtime +30 | rsync -nav --remove-source-files --files-from=- . archive/.

for testing, and

find . -maxdepth 1 -type f -mtime +30 | rsync  -av --remove-source-files --files-from=- . archive/.

for the real thing.

The use of rsync instead of mv is just because rsync supports specifying its source files on standard input. But an added benefit is that rsync has lots of options for detailed control, e.g. dealing with symlinks.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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