9

I would like to move all files and folder from one directory to one of its subfolders. How do I do that?

I am using BusyBox and linux.

ex:

move all files and folder in /my/path/ to /my/path/subfolder/.

Copy, and then delete solutions are not affordable.

Thanks.

7 Answers7

14
mv * subfolder 

Of course, it will fail moving the "subfolder" directory into itself, but everything else will move

2

Solutions that use * (expanded by shell) won't work with too many objects in /my/path/. In such case you'll get:

argument list too long

This approach doesn't use *:

cd /my/path/ &&
find . -mindepth 1 -maxdepth 1 ! -name subfolder -exec mv -t subfolder/ {} +

Unfortunately -mindepth and -maxdepth options of find are not POSIX-compliant; neither -t option of mv is, I think.

This variant should satisfy POSIX:

cd /my/path/ &&
find . ! -name . -prune ! -name subfolder -exec mv {} subfolder/ \;

(I adapted this Unix & Linux SE answer). Sadly it calls mv for every object found, thus it's slow.


Fast alternative approach, if only you can create directories anew (initially neither /my/path/subfolder/ nor /my/subfolder/ should exist):

  • rename path/ to subfolder/,
  • recreate path/,
  • move subfolder/ into path/.

Note on inode-based filesystem this should be equally fast, no matter how many objects there are in path/. The code:

cd /my/ &&
test ! -e subfolder/ && mv path/ subfolder/ &&
mkdir path/ &&
mv subfolder/ path/

In this case I used && a lot to emphasize the procedure should abort if any of its steps fails. However this approach is inconvenient if you need path/ or subfolder/ to have non-default permissions, ownership etc.

2

The simplest way to do this is:

mv !(subfolder) subfolder

'!' means NOT, similar to programming languages, where mv will move all files and folders to the required subfolder with the exception of the subfolder.

Additional things like moving hidden folders and dot folders are described here: https://askubuntu.com/questions/91740/how-to-move-all-files-in-current-folder-to-subfolder

Razetime
  • 1,072
1

Although i'm a bit late, I was in the same situation and came with a different solution that won't trigger anything to stdout, stderr or provide non-null exit code.

In case it can help someone:

items=(*)
mkdir subfolder
mv ${items[*]} subfolder

In case you have filenames containing spaces, you will have to add IFS='' at the first line to properly escape them (which was my case).

0

You might want to check out the mv command. You can try searching for all files and folders in a directory and exclude a sub-directory then copy all found to that sub-directory using find with the mv command.

See a similar stack-overflow question https://stackoverflow.com/questions/4612157/how-to-use-mv-command-to-move-files-except-those-in-a-specific-directory

0

After more digging and experimentation. I found the answer: -prune is used to avoid recusing into sub-directories. ! -name is used to exclude the target sub-directory, and then exec executes the move operation. The {} is replaced with file/directory names from the find command.

find /my/path/* -prune ! -name subfolder -exec mv {} /my/path/subfolder/. +
0

Another way is to temporarily move the subfolder to the parent.

mv subfolder .. && mv * ../subfolder && mv ../subfolder .