Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have two directories images and images2 with this structure in Linux:

/images/ad  
/images/fe  
/images/foo  

... and other 4000 folders

and the other is like:

/images2/ad  
/images2/fe  
/images2/foo

... and other 4000 folders

Each of these folders contain images and the directories' names under images and images2 are exactly the same, however their content is different. Then I want to know how I can copy-merge the images of /images2/ad into images/ad, the images of /images2/foo into images/foo and so on with all the 4000 folders..

share|improve this question
    
are the end files named the same in both directories? –  Simply_Me Aug 12 at 23:06
    
Nope... for example in images/ad are 1.jpg, 2.jpg and 3.jpg. But in images2/ad are 4.jpg and 5.jpg –  inulinux12 Aug 12 at 23:09

3 Answers 3

up vote 1 down vote accepted

This is a job for rsync. There's no benefit to doing this manually with a shell loop unless you want to move the file rather than copy them.

rsync -a /images/ /images2/

If images with the same name exist in both directories, the command above will overwrite /images2/SOMEPATH/SOMEFILE with /images/SOMEPATH/SOMEFILE. If you want to replace only older files, add the option -u. If you want to always keep the version in /images2, add the option --ignore-existing.

If you want to move the files from /images, with rsync, you can pass the option --remove-source-files. Then rsync copies all the files in turn, and removes each file when it's done. This is a lot slower than moving if the source and destination directories are on the same filesystem.

share|improve this answer

@inulinux12 , you can use the following one line for loop from command line:

$ for dir in images2/*; do mv "$dir"/* "${dir/2/}"; done

This will move all of the files from images2 to images in their respective directories. Note: this assumes no files have the same name.

For example:

Before execution:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2
images/adfoo:
jpg.7
images/fe:
jpg.5
images2:
ad  adfoo  fe
images2/ad:
jpg.3
images2/adfoo:
jpg.6
images2/fe:
jpg.4

After execution:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2  jpg.3
images/adfoo:
jpg.6  jpg.7
images/fe:
jpg.4  jpg.5

Hope this helps.

share|improve this answer
    
Thanks for your help! –  inulinux12 Aug 12 at 23:34
    
@inulinux12 glad to help :-) –  Simply_Me Aug 12 at 23:35
2  
Don't parse the output of ls. mywiki.wooledge.org/ParsingLs –  Etan Reisner Aug 12 at 23:48
    
@EtanReisner Thank you for the suggestion; seems pretty narrow scenarios though given the information given in the question. –  Simply_Me Aug 13 at 0:01
1  
@Simply_Me While true that it will usually be fine, you really don't want it to blow up when you hit a case you weren't counting on. It can cause really bad problems. Not to mention that it is quite often (as in this case) almost trivially replaceable with a simple glob. See my answer as an example of that. –  Etan Reisner Aug 13 at 0:04
for dir in images2/*; do mv "$dir"/* "images/$(basename "$dir")"; done

Loop over all the contents of images2 using an expanded glob (to avoid the problems with parsing ls) then mv the contents of those items to the matching entry in images. Uses basename to strip the leading images2 from the globbed path.

share|improve this answer
    
please add more details on what your command does so that it is useful for future readers as well :) –  Ramesh Aug 12 at 23:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.