Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move only files recursively from multiple directories into one directory with mv

I currently have ~40k RAW images that are in a nested directory structure. (Some folders have as many as 100 subfolders filled with files.) I would like to move them all into one master directory, with no subfolders. How could this be accomplished using mv? I know the -r switch will copy recursively, but this copies folders as well, and I do not wish to have subdirectories in the master folder.

like image 484
user1067257 Avatar asked Nov 09 '13 18:11

user1067257


2 Answers

If your photos are in /path/to/photos/ and its subdirectories, and you want to move then in /path/to/master/, and you want to select them by extension .jpg, .JPG, .png, .PNG, etc.:

find /path/to/photos \( -iname '*.jpg' -o -iname '*.png' \) -type f -exec mv -nv -t '/path/to/master' -- {} +

If you don't want to filter by extension, and just move everything (i.e., all the files):

find /path/to/photos -type f -exec mv -nv -t '/path/to/master' -- {} +

The -n option so as to not overwrite existing files (optional if you don't care) and -v option so that mv shows what it's doing (very optional).

The -t option to mv is to specify the target directory, so that we can stack all the files to be moved at the end of the command (see the + delimiter of -exec). If your mv doesn't support -t:

find /path/to/photos \( -iname '*.jpg' -o -iname '*.png' \) -type f -exec mv -nv -- {} '/path/to/master' \;

but this will be less efficient, as one instance of mv will be created for each file.

Btw, this moves the files, it doesn't copy them.

Remarks.

  • The directory /path/to/master must already exist (it will not be created by this command).
  • Make sure the directory /path/to/master is not in /path/to/photos. It would make the thing awkward!
like image 113
gniourf_gniourf Avatar answered Sep 28 '22 01:09

gniourf_gniourf


Make use of -execdir option of find:

find /path/of/images -type f -execdir mv '{}' /master-dir \;

As per man find:

 -execdir utility [argument ...] ;
     The -execdir primary is identical to the -exec primary with the exception that 
     utility will be executed from the directory that holds the current
     file.  The filename substituted for the string ``{}'' is not qualified.

Since -execdir makes find execute given command from each directory therefore only base filename is moved without any parent path of the file.

like image 26
anubhava Avatar answered Sep 28 '22 03:09

anubhava