I have two directories, dirA whicht contains N gb of data and dirB which is supposed to contain only the newest M gb of data from dirA. When files are added to dirA, they sould also be added to dirB, while the oldest files in dirB should be deleted.

The purpose of the find, sort, and awk parts is to get a machine-parsable (i.e. null delimited) list of the newest files, sorted by newest first, and then truncate that list when the accumulated size reaches 2 GiB (the 2147483648 is simply 2*2^30 bytes, or 2 GiB; adjust this number to taste).Note: the less than comparison in the awk part means the size is a hard upper bound (an "at most" condition), so it can result in situations like the following: if the newest file was 4 GiB, nothing would be included in the sync. Move the print $3 to the beginning of the { } to get the opposite behavior ("at least"), in which case you would get the 4 GiB file and end up syncing twice as much as you intended. I assumed the first was more desirable.

The first rsync extracts those files to a temporary location ("$tmpdir") but preserves path (-R a.k.a. --relative). Since it uses hard links (using --link-dest) and not a full copy, this step uses negligible space, but $tmpdir must reside in the same file system as $dirA.

The second rsync invocation does the actual syncing with $dirB and --delete-ing of old files in $dirB not found in $tmpdir. The reason for using the temporary directory and doing this in two steps is I haven't yet found a way to get the deletion part to work in just one step.