How can I move the files contained in all subdirectories to the current directory, and then remove the empty subdirectories?

I found this question, but adapting the answer to:

mv * .

did not work; I received a lot of warnings looking like:

mv: wil and ./wil are identical

The files contained in the subdirectories have unique names.

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 {} \;
  • Is there also a way to skip the question for overwriting the files by not overwrting them? – Filnor Aug 13 at 8:27
  • 1
    Options for mv: -n, --no-clobber: do not overwrite an existing file. You might be interested in -b, --backup, too. – Florian Jenn Aug 17 at 9:24

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 %

Bash 4:

shopt -s globstar
for file in **; do [[ -f "$file" ]] && mv "$file" .; done

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

mv *.* subdir/
mv .* subdir/

Just run this command:-)

mv **/*.* .

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

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.