vote up 5 vote down star
2

I tried something like mv . .. but it doesn't work.

flag

73% accept rate
I don't have enough rep to retag questions, but may I suggest [linux] [mv] [cwd] [files], or something similar? – Stephan202 Oct 28 at 19:33
I have retagged this question per Stephan202's request. – eleven81 Oct 28 at 19:35

6 Answers

vote up 9 vote down check

The command you are looking for is

mv * .* ..

Explanation: the mv command moves files and directories. The last argument to mv is the target (in this case the directory one step "up" in the tree, ..). The arguments before that are the source files and directories. The asterisk (*) is a wildcard which matches all files which do not start with a dot. Files that start with a dot (dotfiles) are "hidden". They are matched using the pattern .*.

See the manpage which I linked for more information on mv.

Edit: as Chris Johnsen correctly points out: the pattern .* also matches . and ... Since you don't want to (and cannot) move those, it's better to use a pattern which matches any filename starting with a dot except those two. The pattern .[^.]* does just that: it matches any filename (1) starting with a dot (2) followed by a character which is not a dot (3) followed by zero or more arbitrary characters.

Edit 2: As Paggas points out, we'd also have to add the pattern .??* in order to match files starting with two dots. See his answer for an alternative solution using find.

Edit 3: Arajan van Benthem's answer mentions shopt in order to avoid all those issues with dotfiles. But then there is still the problem with files starting with a dash. And it requires three commands. Still, I like the idea. I propose to use it like this:

(shopt -s dotglob; mv -- * ..)

This executes shopt in a subshell (thus no second call to shopt required) and uses -- so that files starting with a dash will not be interpreted as arguments to mv.

link|flag
2  
Using .* might cause mv to produce warnings/errors about not being able to move . and ... You might try mv * .[^.]* .. instead. – Chris Johnsen Oct 28 at 19:21
1  
+1 a good & complete answer. Nice. – DaveParillo Oct 28 at 19:22
Very complete answer thanks. – asksuperuser Oct 28 at 19:34
1  
@alain: you're welcome, and welcome to the site! (If (and only if) one of the posts here sufficiently answered your question, then you can mark it as such. That will get the poster 15 extra reputation points, and also give you 2 rep extra.) – Stephan202 Oct 28 at 19:41
I really like the shopt solution running in a subshell :) – Paggas Oct 29 at 20:04
show 1 more comment
vote up 5 vote down

Short answer: use

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Long answer:

The command

mv * .* ..

will not work since .* can match . and ... But the command

mv * .[^.]* ..

will also not work, since .[^.]* won't match, e.g., ..filename! Instead, what I do is

mv * .[^.] .??* ..

which will match everything except . and ... * will match everything that doesn't start with a ., .[^.] will match all 2 character filenames starting with a dot except .., and .??* will match all filenames starting with a dot with at least 3 characters.

Better yet, you can use

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

which avoids the ugly glob hacks in mv * .[^.] .??* ..!

link|flag
+1. Valid concerns. I'll link to your answer. – Stephan202 Oct 28 at 20:34
Thanks :) I would have commented on you post, but I don't have enough reputation yet. – Paggas Oct 28 at 20:38
1  
Also, I forgot to note the importance of -- so that the command works correctly with file names starting with a dash. I have included -- in my find answer though. A more complete answer using globs is "mv -- * .[^.] .??* ..". – Paggas Oct 28 at 20:45
+1: I came back to add ..?* to my comment, and you had already taken care of it. – Chris Johnsen Oct 29 at 3:10
What can possibly be wrong with trying to mv .. ? It simply does nothing and can't do anything. There are other commands where it can do something (chmod and chown) but mv and rm simply don't do anything to . or .. – chris Nov 6 at 4:18
vote up 4 vote down

Just for the sake of completeness, one can also tell the Bash shell to include hidden files, using shopt:

shopt -s dotglob
mv -- * ..
shopt -u dotglob
link|flag
+1. Much cleaner. I think a slight improvement is in order, though. See the update to my answer. – Stephan202 Oct 28 at 21:11
vote up 2 vote down

Ultimately trying mv . will fail because mv won't be able to unlink the directory that you are currently in. You could mv * .. to move the files in the cwd.

link|flag
Hi thanks that worked! – asksuperuser Oct 28 at 19:33
vote up 2 vote down
mv * .??* ../.

* gets all not-dot files. .??* gets all . files at least three bytes long, which works for all legit ones. Anything left you probably want to rm rather than mv anyway.

The ../. doesn't offer any direct benefits over .. but when doing a move-to-directory it is a very good habit to get into, because it will fail, as you want, if there is something wrong with the path. For example, mv xyz bletch, where you think bletch is a directory, can be made more certain with mv xyz bletch/..

link|flag
1  
You might add .[^.] to get cover files like .a. – Chris Johnsen Oct 29 at 3:12
There is no difference between ../ and ../. so I wouldn't bother typing the . after the slash. Also, in the case of mv and rm, it does no harm to include . and .. in the list, ie there isn't anything scary or wrong with mv * .* /path/to/file/, just as rm . or even -rf . doesn't do anything. – chris Nov 6 at 4:21
vote up 1 vote down

mv * ../

(15 characters)

link|flag
This one won't move any hidden/dot files. – Manni Oct 28 at 20:02

Your Answer

Get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.