Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

This is a bit of an embarrassing question, but I have to admit that this late in my career I still have questions about the mv command.

I frequently have this problem: I need to move all files recursively up one level. Let's say I have folder foo, and a folder bar inside it. Bar has a mess of files and folders, including dot files and folders. How do I move everything in bar to the foo level?

If foo is empty, I simply move bar one level above, delete foo and rename bar into foo. Part of the problem is that I can't figure out what mv's wildcard for "everything including dots" is. A part of this question is this - is there an in-depth discussion of the wildcards that cp and mv commands use somewhere (googling this only brings very basic tutorials).

share|improve this question

6 Answers 6

In Bash (and some others), you can use brace expansion to accomplish this in one line:

mv bar/{,.}* .

The comma separates a null and a dot, so the mv command sees filenames that match * and .*

share|improve this answer
    
this attempts to move '..' too, fails with message 'resource is busy'. Works nonetheless. –  Xananax Apr 2 '12 at 10:02
3  
Suggested by anonymous user: To eliminate the error caused by also matching "." and "..", use this command: mv bar/{,.[!.],..?}* . –  HopelessN00b Oct 6 '12 at 2:21

The easiest way to do this is to do it in two command, because * doesn't match .whatever

cd /foo
mv bar/* ./
mv bar/.??* ./

You do not want to use bar/.* which I found out while committing this mistake:

rm -rf ./.* 

This is a BAD THING. Anyone want to guess why? ;-)

share|improve this answer
    
I don't think Bash or Zsh expands .* to . and ... Zsh doesn't for me at least. –  Mikael S Mar 13 '10 at 20:56
    
Mikael: I can promise that bash does (or at least did), as I had to recover user directories that I wiped out by doing just that –  Matt Simmons Mar 13 '10 at 22:07

First thing to know about globbing --it's done by the shell, not the command. Check your shell's man page for all the details.

share|improve this answer

mv .??* * will take care of anything except dot followed by a single character. If that's common for your situation, you can add .[a-zA-Z0-9]*. That will still leave files with names such as .;, .^, and .^I (tab). If you need to handle everything, you'll need to be a bit more complex.

mv .. `ls -f | egrep -v '^.$|^..$'
share|improve this answer

This one harvests all files from subfolders and moves them to current dir

find . -type f -exec mv -iv \{} . \;

If You want to owerwrite files with same name, use

yes y | find . -type f -exec mv -iv \{} . \;
share|improve this answer

If you have a directory structure /foo/bar/ and you want to move all files under bar one step above, go into the bar directory and type the following:

find . -depth -print0 | cpio --null -pvd ../

Generally, I think cpio(1) is better for these kind of tasks. You can check out the detailed documentation by issuing info cpio in your shell.

share|improve this answer

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.