34

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.

Richard
  • 955
  • 5
  • 13
  • 16

6 Answers6

49

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 {} \;
Florian Jenn
  • 824
  • 2
  • 8
  • 12
5
mv */* .

It will move all files from all subdirectories to current directory.

If you need some cleanup, you could use

find . -type d -empty -delete

It will delete all empty subdirectories.

Nikandr Marhal
  • 151
  • 1
  • 1
5

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 %

CodeBrauer
  • 501
  • 4
  • 13
trurl
  • 2,172
  • 1
  • 13
  • 16
0

Bash 4:

shopt -s globstar
for file in **; do [[ -f "$file" ]] && mv "$file" .; done
ata
  • 150
  • 4
-2

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

mv *.* subdir/
mv .* subdir/
HopelessN00b
  • 1,882
  • 3
  • 21
  • 29
Guillermo
  • 97
  • 1
-2

Just run this command:-)

mv **/*.* .