简体   繁体   中英

Synchronize content of directories in Linux

Let's assume I have following source directory

source/
    subdir1/file1
    subdir1/file2
    subdir2/file3
    subdir3/file4

and target directory

target
    subdir1/file5
    subdir2/file6
    subdir4/file7

I would like to move content of source subdirectories to right target subdirectories so result look like this

target
    subdir1/file1
    subdir1/file2    
    subdir1/file5
    subdir2/file6
    subdir2/file3
    subdir3/file4
    subdir4/file7

Is there some Linux command to do this or must I write a script myself?

To suimmarize, it is important to move, not copy. That rules out cp and rsync but allows mv . mv , however, has the issue that it is not good at merging the old directory into the new.

In the examples that you gave, the target directory had the complete directory tree but lacked files. If that is the case, try:

cd /source ; find . -type f -exec  sh -c 'mv "$1" "/target/$1"' _  {} \;

The above starts by selecting the source as the current directory with cd /source . Next, we use find which is the usual *nix utility for finding files/directories. In this case, give find the -type f option to tell it to look only for files. With the -exec option, we tell it to move any such files found to the target directory.

You have choices for how to deal with conflicts between the two directory trees. You can give mv the -f option and it will overwrite files in the target without asking, or you can give it the -n option and it will never overwrite a target file, or your can give it the -i option and it will ask you each time.

In case the target directory tree is incomplete

If the target directory tree is missing some directories that are in the source, the we have to create them on the fly. This adds just minor complication:

cd /source ; find . -type f -exec  sh -c 'mkdir -p "/target/${1%/*}"; mv "$1" "/target/$1"' _  {} \;

The mkdir -p command assures that the directory we want exists before we try to move the file there.

Additional notes

  • The form ${1%/*} is an example of one of the shells powerful features called "parameter expansion". This particular feature is suffix removal. In general, it looks like ${parameter%word} which tells bash to expand word and remove it from the end of parameter . In our case, the name of the parameter is 1 , meaning the first argument to the script. We want to remove the file name and just leave behind the directory that the file is in. So, the word /* tells the shell to remove the last slash and any characters which follow.

  • The commands above use both single and double quotes. They have to be copied exactly for the command to work properly.

To sync dorectory maybe used rsync

Example:

rsync -avzh source/ target/

More info man rsync

Move (no copy)

rsync --remove-source-files -avzh source/ target/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM