Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

5 Answers 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 %

share|improve this answer

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

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

You can run the following from your current directory:

mv ./* .

To be safe, you can cp first:

cp ./* .

Verify that your files have been copied to the current directory, then delete from sub directories.

share|improve this answer
    
This doesn't work. It also doesn't make sense, because every element you'll find with ./* is already in the current directory. –  trurl Nov 10 '11 at 13:25

Your Answer

 
discard

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.