I have a rsync command which scans to find freshly created files and then syncs it with the remote PC. Both PC's have had the same file structure until recently.

find /mnt/movies -type f -ctime -1 -print0 | rsync -0Prvuz --log-file=/home/daisy/rsync/movies.log -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --files-from=- --from0 / daisy@melbourne.11111.net:/

In this case newly created movies from /mnt/movies/ are sent to the destination in the same location (/mnt/movies/).

Now I need to send them to /mnt/drive/movies/ which is a change, but for the life of me I cannot work out how to do this.

I understand the / after --files-from=- --from0 causes rsync to place the output of find into the / directory of the destination, changing the / to /mnt/drive/ causes rsync to create the directory /mnt/movies/... inside the /mnt/drive folder. What I would like to see is /mnt/drive/movies/movie1/1.mkv

Hope someone can help me with this :/

  • 1
    You don't need to have the -0 in your first string of rsync options and the -from0 later on, only one of them, they are the same option. – Arronical Oct 10 '16 at 11:32

I've only partially tested my solution, as I don't have a remote system, but I understand that your problem is syncing from / to / (the entire tree). rsync will accept a source and destination, but find is giving you full paths, so it can only work if you sync the whole tree. My first thought was to use sed to take off the leading part of the paths and then specify the source to rsync so it can find those files, and specify the destination also

find ... | sed -z 's/^\/mnt\/movies\///' | rsync ...

(using -z to tell sed to use NULL separators from -print0 and for --from0)

But, steeldriver helpfully pointed out in a comment that we can achieve the same thing without sed using printf '%P\0' instead of just print0 in the find command, and this does exactly the same as my idea but much more elegantly (discarding the part of the path specified in the command).

Doing this, each file path will be just movie1/1.mkv. So, at the end, instead of --from0 / daisy@melbourne.11111.net:/ tell rsync where to look for that path, and where to find the destination on the remote system:

--from0 /mnt/movies daisy@melbourne.11111.net:/mnt/drive/movies

This works fine for me with local copying.

suggested complete command:

find /mnt/movies -type f -ctime -1 -printf '%P\0' | rsync -Prvuz --log-file=/home/daisy/rsync/movies.log -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --files-from=- --from0 /mnt/movies daisy@melbourne.11111.net:/mnt/drive/movies
  • Very smart. There was a sed based answer here before, but it ended up looking for files with the /drive/ element of the path in them. – Arronical Oct 10 '16 at 11:13
  • I saw it, and the issue with it... I've been puzzling over this for a while on and off! Thanks @Arronical , I hope it works well for OP – Zanna Oct 10 '16 at 11:15
  • I gave it a test, but only locally, and it seemed to work well. I actually think rsync could handle this without the need for any find command, but need to check the method. – Arronical Oct 10 '16 at 11:17
  • 1
    @Arronical I was going to say the same, my first thought when I saw the question was why do you need find? But they have their reasons I guess, I suppose they have old files they don't want to sync and without knowing exactly I would end up giving too many options. But some rsync guru will surely know... – Zanna Oct 10 '16 at 11:23
  • 1
    Couldn't you just replace -print0 by -printf '%P\0' in the find command, instead of using sed? – steeldriver Oct 10 '16 at 14:26

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.