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

I have a number of subdirectories and I would like to move any files contained therein to the current directory using a one line Terminal command on the Mac. I know that my file names are not all unique and would like to add a suffix before the file extension.

I found a similar question Q: Move all files in sub-directories to current directory? which suggests using:

find ./*/* -type f -print0 | xargs -0 -J % mv % . 

But that's only helpful with unique filenames. For example, given the following tree:

├── bar
│   ├── test1.jpg
│   ├── test2.jpg
│   └── test3.jpg
├── foo
│   ├── test1.jpg
│   ├── test2.jpg
│   └── test3.jpg
├── qux
│   └── test3.jpg
└── corge
    └── test3.jpg

I would like to see a result similar to:

├── bar
├── foo
├── qux
├── corge
├── test1.jpg
├── test1a.jpg
├── test2.jpg
├── test2a.jpg
├── test3.jpg
├── test3a.jpg
├── test3b.jpg
└── test3c.jpg

Can anyone help?

share|improve this question
I see now, thanks for including the example. Short of writing a small script to check whether the file exists and renaming it there, I can't think of anything better. I'd give it a shot when I'm back on a computer. – slhck Oct 25 '13 at 20:38

Unless the strict sequencial naming in your example is super-important to you, I would propose the following "keep it simple" / "quick & dirty" solution instead:

find . -type f |
while read filename; do
    basename=$(basename "$filename");
    newname=$(echo "$basename" | sed "s/^\(.*\)\(\.[^\.]\+\)$/\1(XXXX)\2/");
    printf "mv \"%s\" \"%s\";\n" "$filename" "$(mktemp -u "$newname")";

This only prints the commands that would be executed, so check for sanity by reviewing the output, then copy & paste into commandline, if all is to your satisfaction.

In english: find me all regular files, transform me their filenames from "test1.jpg" into form "test1(XXXX).jpg", where "XXXX" will be picked up and replaced by mktemp with random characters, then create the "mv" commandline for this action.

To decrease filename collision risk further, simply add more "X"es to it.

Have fun.

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.