how to add cache control in AWS S3?

My bucket has mp4, jpg, and other files. The files I wanted to update are stored in a "sub-bucket" (ex: https://s3.amazonaws.com/my.bucket/sub-directory/my-video.mp4). In my case I only wanted to update the cache control on mp4 files:

aws s3 cp \
   s3://my.bucket/sub-directory/ s3://my.bucket/sub-directory/ \
   --exclude '*.jpg' --exclude '*.png' \
   --cache-control 'max-age=31104000' \
   --recursive

To test out what this will do, you can use the --dryrun flag:

aws s3 cp --dryrun \
   s3://my.bucket/sub-directory/ s3://my.bucket/sub-directory/ \
   --exclude '*.jpg' --exclude '*.png' \
   --cache-control 'max-age=31104000' \
   --recursive

Also with the AWS's own client:

aws s3 sync /path s3://yourbucket/ --cache-control max-age=604800

Please try the current upstream master branch (https://github.com/s3tools/s3cmd), as it now has a modify command, used as follows:

./s3cmd --recursive modify --add-header="Cache-Control:max-age=86400" s3://yourbucket/

To adjust metadata such as cache-control on an object in S3 without having to re-upload it and without having to use any third party tools, you can do the following with the AWS CLI. It copies the object to itself while overriding the metadata with your chosen settings:

aws s3api copy-object --copy-source <bucket-name>/<file> --bucket <bucket-name> --key <file> --metadata-directive REPLACE --cache-control "max-age=3600"

Process this command in a find to do it on an existing set of files that already exists in the bucket as you mention:

find . -type f -exec aws s3api copy-object --copy-source <bucket-name>/{} --bucket <bucket-name> --key {} --metadata-directive REPLACE --cache-control "max-age=3600"

replace <bucket-name> with the name of your bucket

WARNING: this will overwrite all your existing metadata on the files such as acl, just add additional flags to the command to set what you need, e.g., --acl public-read to give full public access. (thanks @jackson)