Move every file that is not a directory

I have a directory that I am trying to clean out that contains both files and subdirectories. What I am trying to do is simple: move all the files into another directory, but leave all the sub-directories as they are.

I am thinking something like:

mv [*_but_no_dirs] ./other_directory

It seems like there should be a simple way to do this with wildcards * and regex…

Anyone have ideas?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Regex aren’t involved here. Wildcards in bash (like most other shells) only match files based on the file names, not based on the file type or other characteristics. There is one way to match by type: adding / at the end of the pattern makes it only match directories or symbolic links to directories. This way, you can move directories, then move what’s left, and move directories back — cumbersome but it works.

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * other_directory/
mv "$tmp"/* .
rmdir "$tmp"

(that approach should be avoided if the current directory is the mount point of a filesystem, as that would mean the moving of directories away and back would have to copy all the data in there twice).

A standard way to match files by type is to call find.

find . -name . -o -type d -prune -o -exec sh -c 'mv "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="674327">[email protected]</a>" "$0"' other_directory/ {} +

(also moves symlinks, whether they point to directories or not).

In zsh, you can use glob qualifiers to match files by type. The . qualifier matches regular files; use ^/ to match all non-directories, or -^/ to also exclude symbolic links to directories.

mv -- *(.) other_directory/

In any shell, you can simply loop.
for x in *; do
   if [ ! -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done

(does not move symlinks to directories).

Method 2

You could use something like

find . -maxdepth 1 ( ! -type d ) -exec sh -c 'mv  "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="be9afe">[email protected]</a>" MYDIR' _ {} ;

First we use find to look only within the current directoy, then we ignore directories by using ! -type d finally we execute sh and move everything to the destination dir. You might try {} + at the end which will be faster.

Method 3

It’s potentially a bit dangerous but

cp * destination/
rm *

As both cp and rm won’t operate on directories without the -r switch.

Method 4

Here is a simple 1 line command to achieve what you are trying to do:

find ./sourceDir -maxdepth 1 -type f | xargs mv -t ./targetDir

Explanation
  1. Find all the files you want at depth 1 only, that are of type files. You can find explanation here.
    https://linux.die.net/man/1/find
  2. Pipe that using “| xargs” to mv.
    https://linux.die.net/man/1/xargs
  3. tell mv where to move the files
    https://linux.die.net/man/1/mv

This 1 liner is fairly portable, and can be run from anywhere in the system as long as you have the sourceDir and targetDir, either as full paths or relative paths.

Method 5

find . -maxdepth 1 -type f|awk '{ gsub( "40", "\40"); print}' | xargs -I{} mv {} /path/to/dest/directory/{}

Please ensure you are in the current directory where your files to be moved are present while executing the command.

find . -maxdepth 1 -type f will find all the files in the folder .

awk '{ gsub( "40", "\40"); print}' will replace “space” ( ) with “space” ( ) . 40 is the octal for “space”. This ensures that files with spaces in their names are also included.

xargs -I{} mv {} /path/to/dest/directory/{} will capture the piped output as an argument and then {} will substitute the argument value i.e., filenames from previous command in {} of mv {} /path/to/dest/directory/{} source and destination arguments.

This command will ensure that files that has spaces in their names are moved as well.

Method 6

mv $(find /my/source/directory -maxdepth 1 -type f) /my/destination/directory

Move will take a list of arguments, so when you ask find to give you everything that is of type “file” within /my/source/directory, it will move them one by one to /my/destination/directory. If you wanted to include the files in the subdirectories, too, while leaving the directory structure intact, remove -maxdepth 1 from the above command.

Method 7

if [ -f "$PATH/$FILE_NAME" ]; then mv "$PATH/$FILE_NAME" "$OTHER_PATH/$FILE_NAME"; fi;

Method 8

I would suggest simply doing mv *.* destination/ with destination/ being the folder you are moving to.

Method 9

If you don’t intend to move dotfiles (e.g. “.foobar”), too, you can simply do:

mv * /some/destination/

If you do, see the above answer with find’s -maxdepth.

Method 10

mv $(ls -l | grep "^-" | awk '{print $9}') ./folder_where_move


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments