Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

We're developing a java product that's installed via rpm. We have a set of config files that a user can edit. These config files are java properties files in the form:

com.acme.pkg1.setting=something customized 1
com.acme.pkg2.setting=something original 2

These files are marked in the SPEC file with %config(noreplace), so after an upgrade, we could have an .rpmnew file next to it:

com.acme.pkg1.setting=something original 1
com.acme.pkg2.setting=something original 2
com.acme.pkg3.setting=something original 3

Is there a way to merge these files in such a way that only new keys are added to the original file?

My idea was:

  1. filter the keys
  2. sort the keys
  3. use comm(1), something like: comm -23 file.rpmnew.keys file.keys > new.keys
  4. extract key=value from file.rpmnew matching new.keys
  5. append result to original file

How can we achieve all this in from an rpm post-update script?

Preferably using only standard linux utilities (comm, diff, sed, awk, grep, ...)?

share|improve this question
up vote 2 down vote accepted
  • Build raw original and raw target values without settings:

    sed "s/=.*//g" file_original.ini > file_original.raw
    sed "s/=.*//g" file_target.ini > file_target.raw
  • I assume that target will have more options than the original. Build the difference:

    grep -vf original.raw target.raw > newvals.dat
  • Add the new Values:

    cp -p file_original.ini file_original.ini.rpmsave
    grep -f newvals.dat file_target.ini >>file_original.ini

That`s the basic idea. It needs lots of error handling, clean tmp-file creation and tidying up.

share|improve this answer
Great idea to use grep -vf. To avoid any false matches, I had to escape "." in the keys before passing it to grep -f. A simple 'sed "s/\./\\\./g"' did the trick. – greyfairer Dec 14 '11 at 9:56

Your Answer


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.