- How do you move all files (including hidden) from one directory to another?
- 12 Answers 12
- Zsh
- Bash
- Ksh93
- Standard (POSIX) sh
- GNU find and GNU mv
- Standard find
- Bash
- Ksh93
- Zsh
- From man bash
- Moving folder and subfolder to another path
- 6 Answers 6
- Edit
- You must log in to answer this question.
- Linked
- Related
- Hot Network Questions
- Subscribe to RSS
How do you move all files (including hidden) from one directory to another?
How do I move all files in a directory (including the hidden ones) to another directory? For example, if I have a folder «Foo» with the files «.hidden» and «notHidden» inside, how do I move both files to a directory named «Bar»? The following does not work, as the «.hidden» file stays in «Foo».
mkdir Foo mkdir Bar touch Foo/.hidden touch Foo/notHidden mv Foo/* Bar/
Sadly, this question ended up here because I said on SO that it should move here or SU, so of course it moved here when there was a duplicate on SU already 🙂
Personally, I think *nix specific questions and answers should be off-topic on SU. With the current rules we end up with tons of content collisions between the two — like this question.
12 Answers 12
Zsh
setopt -s glob_dots mv Foo/*(N) Bar/
(Leave out the (N) if you know the directory is not empty.)
Bash
shopt -s dotglob mv Foo/* Bar/
Ksh93
If you know the directory is not empty:
Standard (POSIX) sh
for x in Foo/* Foo/.[!.]* Foo/. *; do if [ -e "$x" ]; then mv -- "$x" Bar/; fi done
If you’re willing to let the mv command return an error status even though it succeeded, it’s a lot simpler:
GNU find and GNU mv
find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- <> +
Standard find
If you don’t mind changing to the source directory:
cd Foo/ && find . -name . -o -exec sh -c 'mv -- "$@" "$0"' ../Bar/ <> + -type d -prune
Here’s more detail about controlling whether dot files are matched in bash, ksh93 and zsh.
Bash
$ echo * none zero $ shopt -s dotglob $ echo * ..two .one none zero
There’s also the more flexible GLOBIGNORE variable, which you can set to a colon-separated list of wildcard patterns to ignore. If unset (the default setting), the shell behaves as if the value was empty if dotglob is set, and as if the value was .* if the option is unset. See Filename Expansion in the manual. The pervasive directories . and .. are always omitted, unless the . is matched explicitly by the pattern.
$ GLOBIGNORE='n*' $ echo * ..two .one zero $ echo .* ..two .one $ unset GLOBIGNORE $ echo .* . .. ..two .one $ GLOBIGNORE=. $ echo .* ..two .one
Ksh93
Set the FIGNORE variable. If unset (the default setting), the shell behaves as if the value was .* . To ignore . and .. , they must be matched explicitly (the manual in ksh 93s+ 2008-01-31 states that . and .. are always ignored, but this does not correctly describe the actual behavior).
$ echo * none zero $ FIGNORE='@(.|..)' $ echo * ..two .one none zero $ FIGNORE='n*' $ echo * . .. ..two .one zero
You can include dot files in a pattern by matching them explicitly.
$ unset FIGNORE $ echo @(*|.[^.]*|. *) ..two .one none zero
To have the expansion come out empty if the directory is empty, use the N pattern matching option: ~(N)@(*|.[^.]*|. *) or ~(N:*|.[^.]*|. *) .
Zsh
% echo * none zero % setopt dot_glob % echo * ..two .one none zero
. and .. are never matched, even if the pattern matches the leading . explicitly.
You can include dot files in a specific pattern with the D glob qualifier.
Add the N glob qualifier to make the expansion come out empty in an empty directory: *(DN) .
Note: you may get filename expansion results in different orders (e.g., none followed by .one followed by ..two ) based on your settings of the LC_COLLATE , LC_ALL , and LANG variables.
Why nullglob ? It would make more sense to abort the mv command (like fish, csh/tcsh, zsh (without (N) ) do, or bash with failglob) than running a mv /Bar/ command which makes little sense.
I’d say your GLOBIGNORE description is inaccurate and misleading. Setting GLOBIGNORE to a non-empty value turns on dotglob and makes that . and .. are never matched (like in other sensible shells like zsh, fish, pdksh and derivatives) even if you turn dotglob back off afterwards. ( GLOBIGNORE=:; shopt -u dotglob; echo .* won’t output . and .. ). setting GLOBIGNORE to . or . or : have the same effect.
ksh93 always ignoring . and .. seems to have been broken in between ksh93k+ (where it worked) and ksh93m (where it no longer works). Note that it’s bad in that ksh93 will take the value of FIGNORE from the environment, so a FIGNORE=’!(..)’ env var for instance can create havoc.
#!/bin/bash shopt -s dotglob mv Foo/* Bar/
From man bash
dotglob If set, bash includes filenames beginning with a ‘.’ in the results of pathname expansion.
With the caveat that this command returns an error code if the directory was empty (even though the command actually performed as intended).
@Gilles, the error will then be from mv complaining that that file called Foo/* doesn’t exist. Interestingly, if Foo is searchable, but not readable, and there is a file called * in there, you’ll get no error, that file will be moved, but not the other ones in the directory. bash has a failglob option so it behaves more like zsh , fish or csh / tcsh and abort the command with an error when a glob cannot be expanded instead of that bogus behaviour of leaving the glob as-is.
A simple way to do this in bash is
But this will also move directories.
If you want to move all files including hidden but don’t want to move any directory you can use a for loop and test.
find Foo/ -type f -exec mv -t Bar/ <> \+
The -type f restricts the find command to finding files. You should investigate the -type , -maxdepth , and -mindepth options of find to customize your command to account for subdirectories. Find has a lengthy but very helpful manual page.
I find that this works well for bash and there’s no need to change shell options
So as G-man stated, my original answer is not posix compliant and is pretty much the same as ndemou’s answer above with one change, which is to use brace expansion to create lists of strings which are then acted on. This just means you don’t need to cd into the source directory. Not that big a change really, but it is different.
example: let’s say you have the following layout already.
$ tree -a . ├── destdir └── sourcedir ├── ..d1 ├── ..d2 ├── ..double ├── file-1 ├── file-2 ├── .hidden-1 ├── .hidden-2 ├── . t1 └── . t2
The original question only mentioned hidden files with a single period, but let’s say there are some with two or more periods at the start of the name. You can just add in an additional expression into the braces. We can then execute
This gets expanded to the following:
mv sourcedir/file-1 sourcedir/file-2 sourcedir/.hidden-1 sourcedir/.hidden-2 sourcedir/..d1 sourcedir/..d2 sourcedir/..double sourcedir/. t1 sourcedir/. t2 destdir/
You should now see all files located in destdir:
$ tree -a . ├── destdir │ ├── ..d1 │ ├── ..d2 │ ├── ..double │ ├── file-1 │ ├── file-2 │ ├── .hidden-1 │ ├── .hidden-2 │ ├── . t1 │ └── . t2 └── sourcedir
You can do some pretty cool things with braces in bash with even more additions in 4.x. Check out bash-hackers for some nifty examples.
This basically duplicates ndemou’s answer except you added curly braces (without explaining them). But (1) your answer doesn’t match files whose names begin with .. , and (2) to be POSIX compliant, you should use ! instead of ^ ; i.e., .
@G-Man, sorry about that. So you are correct and my bad for not seeing ndemou’s response. They are pretty much the same thing. 1. thank you for pointing out my version is not posix compliant. 2. I’m using the brace expansion to create lists of strings which the shell will then use to perform an action on. This also means I don’t need to cd into the source directory to act on the files or write out the same file paths over and over to express the paths to all files. I’ll update the example shortly to give any readers a better picture of what I’m talking about.
$ cp -r myfolder/* destinationfolder
cp -r means copy recursive, so all folders and files will be copied.
You can use the remove command rm to remove a folder:
rsync -axvP --remove-source-files sourcedirectory/ targetdirectory
This works because in rsync the trailing slash matters, sourcedirectory/ refers to the content of the directory, while sourcedirectory would refer to the directory itself.
The disadvantage of this method is that rsync will only cleanup the files after the move, not the directory. So you are left with an empty sourcedirectory tree. For workarounds for that, see:
So while this might not be optimal for move operations, it can be extremely useful for copy operations.
For minimal Linux distros, the following ought to work. First, perform a basic move all (which misses the hidden files). Then, move all the hidden files (including the . and .. which will not actually be moved).
mv /sourceDir/* /destinationDir 2> /dev/null mv /sourceDir/.* /destinationDir 2> /dev/null
Notes: If there is no visible content, the first command will produce an error message. The second command will always produce an error saying it can’t move . and .. . As such, just pipe the errors into /dev/null (as shown).
If you need this as a one-liner, simply combine them with a semi-colon:
mv /sourceDir/* /destinationDir 2> /dev/null; mv /sourceDir/.* /destinationDir 2> /dev/null
when combined with this mv
Answer for bash/fish
Here’s a way to do it using wildcards:
.[!.]* . * will match all hidden files except . and ..
.[!.]* . * * will match all files (hidden or not) except . and ..
And to answer the particular example of this question you need cd foo && mv .[!.]* . * * ../bar
Explanation
.[!.]* matches file-names starting with one dot, followed by any character except the dot optionally followed by any string. This is close enough but it misses files starting with two dots like ..foo . To include such files we add . * which matches file-names starting with two dots, followed by any character, optionally followed by any string.
You can test these wildcards with the commands below. I’ve tried them successfully under bash and fish. They fail under sh, zsh, xonsh.
mkdir temp cd temp touch a .b .bc ..c ..cd . d . de ls .[!.]* . * # you get this output: .b .bc ..c ..cd . d . de # cleanup cd .. rm -rf temp
Moving folder and subfolder to another path
I need to move my folder with many subfolders to another path. I’m using putty and this is what I tried: MV -r fromflderpath tofolderpath What am I doing wrong?
6 Answers 6
The mv command doesn’t have an -R flag, it moves folders recursively:
Edit
If you want a file not to be replaced, use the -i for being prompted in case a file with the same name exists.
:I’ve a file,i’ve to move this to another directory but in this directory,i’ve a file with same name.what is the command to move it ,if i move,will i get replaced.
am I missing something here? mv moves a folder and all its contents without any flags. no cp -r;rm -r needed
For those trying to move folder, on Ubuntu using Putty, just use the following command:
sudo mv /root/folder1 /home/folder2/
«/» in the end means you are going to move folder1 inside folder2
If you don’t, you will get «no such file or directory»
I tested on Ubuntu 20.04, and found that we don’t need the / at the end. with or without / , the results are the same: move folder1 to the inside of folder2. But anyways, it’s good practice to put the trailing / at the end, just in case of some mistakes.(check this out).
mv src_folder target_folder/src_folder
i.e. not mv src_folder target_folder/
If it’s hard to use pure shell commands, then you can install Midnight Commander, console application that makes it easier:
In Midnight Commander to move folder or file from one panel to another is F6 , copy F5 .
If you need root access
If you want to have a mouse support
If you want to empty fromflderpath without renaming it, stand in the folder and use
sudo mv source_folder/* target_folder/
source_folder/file.ext source_folder/bin/image.jpg source_folder/etra/info.text
all of them will be moved under target_folder like:
target_folder/file.ext target_folder/bin/image.jpg target_folder/etra/info.text
You must log in to answer this question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533
Ubuntu and the circle of friends logo are trade marks of Canonical Limited and are used under licence.
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.