1

although there are many rsync examples out there, my question: Is there a rsync only command line which copies certain file types (like. .mp3) into one single folder !without using any find command! and !without any! recreation of dir structure on dest folder? (Even if this would result in a huge directory?)

1 Answers1

1

There is no way to get rsync to copy files recursively from a directory hierarchy into a single flat directory. This is easiest done using find:

find source-dir -name '*.mp3' -type f -exec cp {} dest-dir/ \;

The above looks in source-dir for any regular file whose name ends in .mp3, and copies it to dest-dir (name collisions are not handled).

With GNU tools, this can be made more efficient so that cp is called as few times as possible:

find source-dir -name '*.mp3' -type f -exec cp -t dest-dir/ {} +

There's nothing stopping you from calling rsync in place of cp, of course:

find source-dir -name '*.mp3' -type f -exec rsync -a {} dest-dir/ \;

Or, more efficiently,

find source-dir -name '*.mp3' -type f -exec sh -c 'rsync -a "$@" dest-dir/' sh {} +

If you can guarantee that you have less than a few thousand files and if you have a shell that supports the ** filename globbing pattern (as with shopt -s globstar in bash):

rsync -a --no-r source-dir/**/*.mp3 dest-dir/

This does, however, not let you check the file type of the matched pathnames, and it would only match non-hidden names. In the zsh shell, you could use source-dir/**/*.mp3(.D) to only select (possibly hidden) regular files. In the bash shell, you would need to iterate over the matching pathnames and test each with the -f test. You must also set the dotglob shell option to match hidden names.

Kusalananda
  • 333,661
  • Can you explain -exec sh -c 'rsync -a "$@" dest-dir/' sh {} +? Why does sh occur twice? – gerrit Mar 22 '24 at 14:46
  • 1
    @gerrit This should hopefully answer that: https://unix.stackexchange.com/questions/152391/bash-c-with-positional-parameters – Kusalananda Mar 22 '24 at 15:38