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 want to replace all files in a target path with the same name as original.file AND the same hash as orignal.file with new.file. What's the command to do this?

Say I have updated the contents of a file, and now I want all other copies of that file in a certain path to be updated as well.

In most cases the following code would work:

find /target_path/ -iname "original.file" -exec cp new.file '{}' 

However if original.file is readme.txt for example, many unrelated files would be overwritten.

share|improve this question
1  
Why keep multiple copies of the same file if content never differ? Can you use symbolic or hard links for this purpose? –  alex Jun 15 '11 at 11:59
    
I don't know Pacifika thoughts, but I happen to have multiple copies of same file in revision control. Hard or symbolic links are a no go, since different OS have different implementations of soft and hard links. –  bbaja42 Jun 15 '11 at 16:54
add comment

2 Answers 2

up vote 3 down vote accepted

This this will require a test to see if the checksums match before decide to run the cp, you will have to run a subshell as the -exec argument to find. This should do the job:

find /target_path/ -iname "original.file" -exec bash -c \
  '[[ $(md5sum "original.file") = $(md5sum "{}") ]] && cp "new.file" "{}"' \;
share|improve this answer
add comment

It would be easier for you if you can make all identical copies of files hard links. One way to do that is with fdupes: run fdupes -L. Then change files in place; this will preserve hard links.

If all you want to do is find a file by name and content or by name and hash, just add another condition to your find command.

find /target_path/ -iname "original.file" -exec cmp old.file {} -exec cp new.file {}
find /target_path/ -iname "original.file" \
                   -exec sh -c 'test "$(md5sum | sed "s/ .*//")" = "$1" <"$0"' {} "$(cat old.md5sum)" \
                   -exec cp new.file {}

You don't say what your application is; it may or may not help to involve unison, which can detect identical files at different paths when doing remote synchronization.

share|improve this answer
add comment

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.