I am trying to create an rsync job that syncs src /foo/bar/.jpg to dest /foo/.jpg, skipping mid level directories but preserving the top level. i'm sure there is a way to do this with --include --exclude options but i haven't been able to to figure it out.

This is the src structure;

    ├── foo1
    │   └── bar
    ├── foo2
    │   └── bar
    └── foo3
        ├── image1.jpg
        ├── image2.jpg
        ├── image3.jpg
        └── image4.jpg

This is what I'm aiming for at the dest;

        ├── image1.jpg
        ├── image2.jpg
        ├── image3.jpg
        └── image4.jpg

I have tried;

rsync -avhW --include='*.jpg' --exclude='*' src dest

but it's not even finding the .jpg files so i guess the exclude option is overriding it, however i thought there was an order of operation to the filters.

  • is it mandatory to use rsync? Feb 19, 2021 at 16:54
  • ideally yes, not included above but i have added options that allow delete files from src and have this update at dest. unless this can also be done using your method? Feb 19, 2021 at 16:59
  • perhaps you can add that to the question or i would have suggested a simple cp Feb 19, 2021 at 17:10
  • If you want to copy all *.jpg files anywhere in YYMMDD/, have a look at unix.stackexchange.com/questions/2161, but AFAIK there's no way to flatten the target directory. The simple solution would be: rsync -avhW src/YYMMDD/foo3/ dest/YYMMDD.
    – Freddy
    Feb 19, 2021 at 18:51

1 Answer 1


You could just copy up the files.


mkdir -p "$dst/$dir"
rsync -av "$src/$dir"/*/*.jpg "$dst/$dir/"

If YYMMDD represents a series of directories use a loop to iterate across them

for dir in "$src"/??????
    mkdir -p "$dst/${dir##*/}"
    rsync -av "$dir"/*/*.jpg "$dst/${dir##*/}/"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .