Pregunta

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.

¿Fue útil?

Solución

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!

Otros consejos

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.

find <base location of files> -type -f -name \*\.raw -exec mv {} master \;

If your hierachy is only one level deep, here is another way using the automated tools of StringSolver:

mv -a firstfolder/firstfile.raw firstfile.raw

The -a options immediately applies the similar transformation to all similar files at a nesting level 1 (i.e. for all other subfolders). If you do not trust the system, you can use other options such as -e to explain the transformation or -t to test it on all files.

DISCLAIMER: I am a co-author of this work for academic purposes, and working on a bash script renderer. But the system is already available for testing purposes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top