14

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).

6 Answers6

19

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 .*

3

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 \{} . \;
michelek
  • 131
2

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? ;-)

Matt Simmons
  • 20,584
2

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.

1

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 '^.$|^..$'
mpez0
  • 1,512
0

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.

fim
  • 497
  • 2
  • 5