Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

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've got files in a bunch of subdirectories, and I'd like to flatten them out and move them all to the current directory.

I found this question, but adapting the answer to:

mv * .

didn't work. I just got a lot of warnings looking like:

mv: wil and ./wil are identical

Can anyone help?

I know the files all have unique names, if that helps.

share|improve this question

You can also use the -mindepth option:

find . -type f -mindepth 2 -exec mv -i -- {} . \;

(Together with -maxdepth you could also limit the hierarchy levels from which to collect the files.)

I used mv -i (“interactive”) to make mv ask before overwriting files. With a lot of subdirectories, there may be name clashes you'd like to be warned about.

The -- option stops option processing, so mv doesn't get confused by filenames starting with a hyphen.

Clean up the whole bunch of empty subdirectories with

find . -depth -mindepth 1 -type d -empty -exec rmdir {} \;
share|improve this answer

Try this:

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

More Info: Try the find-stamement alone, it should give you a list with all the files you want to move (leave out the -print0). Example:

probe:test trurl$ find ./*/* -type f
./test_s/test_s_s/testf4
./test_s/test_s_s/testf5
./test_s/testf1
./test_s/testf2
./test_s/testf3
./test_s2/testf6
./test_s2/testf7

with -print0 and xargs you are now creating a list of statements to be executed. The -J % flag means, insert the list element here, so mv $FILE . is executed for every file found.

The above is working for the BSD xargs. If you're using the GNU-version (Linux) take -I % instead of -J %

share|improve this answer

Bash 4:

shopt -s globstar
for file in **; do [[ -f "$file" ]] && mv "$file" .; done
share|improve this answer

1 quick trick, only works if your files have extensions (with a dot):

mv *.* subdir/
mv .* subdir/
share|improve this answer

Just run this command:-)

mv **/*.* .

share|improve this answer
1  
That won't find files that don't have a . in their name, will it? – G-Man Oct 4 '14 at 20:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .