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##*/}/"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.