Shell cp full path of directories

Hello everyone.

I'm trying to backup modified folders (with content), but I don't know how to copy full path.

Explanation :
I'm in my user directory,
I modified DOCUMENTS/FIRST-FOLDER/.../LAST-MODIFIED-FOLDER/file.txt in the last 24 hour.

Here's what I do :

$ find . -type d -mtime -1 >backup.txt
$ sed -e 's/^/cp -Rvp /' backup.txt >backup2.txt
$ sed -e 's/$/ WHERETOBACKUP/' backup2.txt >backup3.txt
$ sh <backup3.txt


It only copies LAST-MODIFIED-FOLDER in WHERETOBACKUP, it does not recreate the full path (DOCUMENTS/FIRST-FOLDER/.../LAST-MODIFIED-FOLDER/file.txt)

How can I do this ?

I precise, I'm a beginner :-D...

Thank you very much
 
You have to extract the path from each line. Your current script ends up doing something like this:
contents of backup.txt:
Code:
./DOCUMENTS/FIRST-FOLDER/.../LAST-MODIFIED-FOLDER/file.txt
backup2.txt is going to look like this:
Code:
cp -Rvp ./DOCUMENTS/FIRST-FOLDER/.../LAST-MODIFIED-FOLDER/file.txt
And backup3.txt:
Code:
cp -Rvp ./DOCUMENTS/FIRST-FOLDER/.../LAST-MODIFIED-FOLDER/file.txt WHERETOBACKUP/

cp(1) copies files, not directory structures. So you simply end up with file.txt in the WHERETOBACKUP/ directory. Same as doing cp /some/really/long/path/to/some/where/file.txt destination_dir/, it simply copies file.txt to the directory destination_dir. The -R is recursive, yes, but only if the source is a directory, so cp -R DOCUMENTS WHERETOBACKUP/ will copy the entire DOCUMENTS directory (sub-directories and all) to WHERETOBACKUP/.

You will have to do a lot more scripting if you also want to copy the directory structure. You'll need to use dirname(1) to extract the directory, then add it to the 'base' destination directory, make sure the target directory actually exists (mkdir(1)), then copy that file to the target directory.

It's probably a lot simpler if you used net/rsync. It's typically used to copy files over the network, but it works just as well for local directories. Not only does this take into account file changes (and only copies those) it can also copy entire directory structures.
rsync -avr DOCUMENTS WHERETOBACKUP/DOCUMENTS
 
assuming the directories changed are not included one in another
tar --files-from backup.txt -cf -|tar xvf - -C /where/you/have/thebackup/
or
find . -type d -mtime -1| tar --files-from - -cf -|tar xvf - -C /where/you/have/thebackup/

this commands will copy full directories that have changed files
if you want just the modified files use find -type f
 
Your technical spec is challenging, as the unmodified parents of modified directories will need to be made in the destination.

Rsync will copy modified files, and create the destination directory hierarchy they need automatically. This is not what you asked for. It may be what you want. In default mode rsync(1) does not copy hard links, extended attributes, or ACLs. It will also expand sparse files (which can sometimes be extremely problematic). It will only copy files from the source that either don't exist in the destination directory, or have changed since the last time you did the same rsync. So, it's an excellent method for replication of two directories, and periodically keeping them replicated with minimal copying. If you care to preserve all the original metadata, use rsync -SHAXax. Rsync also has options to manage file and directory deletions.

To copy all the ordinary files in every modified directory (which is what you asked for), I would use cpio(1), but you have to manage the creation of all the potential destination directories:
Code:
#!/bin/sh
SOURCE=source_directory
export DEST=destination_directory
test -d $DEST || { echo "no destination directory: \"$DEST\""; exit 1; }
cd $SOURCE || { echo "no source directory: \"$SOURCE\""; exit 1; }
# First replicate the entire directory structure
find . -type d -depth -print | cpio -pdmu $DEST
# Now copy all the ordinary files in any directory that has been modified
find . -depth -type d -mtime -1 | while read d
do
    find $d -type f -depth 1 -print | cpio -pdmuv $DEST
done
Handling file and directory deletions using the cpio method would require extra work.
 
Wow... thank you guys. I have a few hours in front of me to try your solutions.
Thanks a lot.
This Forum is my first computer forum. I really really like how much people are answering when we ask a question. It's very useful to learn this way !
Thank you again.
 
It sounds like you want to clone file system hierarchies from one location to another and this can be easily achieved with sysutils/clone. Without additional options it clones hard links, extended attributes and ACLs as well (like rsync with all the command line options, but clone does it more complete). It can be used in synchronize and incremental mode, so it would copy only those files which were changed - see: clone(1).

It seems that you are looking for:
clone -s ~/Documents /path/to/the/Backup

The -s flag tells it to sychronize Backup with Documents. In this mode clone copies over only changed files and directory trees.

You could use it in your script as well, by simply replacing cp -Rvp with clone.
 
Last edited:
This is similar to something I've been having a ton of trouble getting used to on FreeBSD specifically due to muscle memory. At least, I hope this is on topic enough. I habitually cp -aR but cp -aR/ by accident does something totally different. Is there some way I can guard against this accident?
 
Back
Top