Replace Stub Values In One Group Of Files With Actual Values From Another Group Of Files

I have two directories of files (new-config-files and old-config-files):

new-config-files/this-db/config.inc.php
new-config-files/that-db/config.inc.php
new-config-files/old-db/config.inc.php
new-config-files/new-db/config.inc.php
new-config-files/random-database/config.inc.php
etc.

old-config-files/this-db/config.inc.php
old-config-files/that-db/config.inc.php
old-config-files/old-db/config.inc.php
old-config-files/new-db/config.inc.php
old-config-files/random-database/config.inc.php
etc.

Example snippet of old file:

$cfg['Servers'][$i]['user'] = 'test-user';
$cfg['Servers'][$i]['password'] = 'test-user-password';
$cfg['Servers'][$i]['only_db'] = 'test-data';

Example snippet of new file:

$cfg['Servers'][$i]['user'] = 'DB-USER';
$cfg['Servers'][$i]['password'] = 'DB-PASSWORD';
$cfg['Servers'][$i]['only_db'] = 'DB-DATABASES';

I'd like to replace only the stub values (i.e., DB-USER, DB-PASSWORD, DB-DATABASES) in the new config files with the corresponding actual values (i.e., test-user, test-user-password, test-data) from the old config files.

It might also be good to know how to do this when there are no stub values, but only different values that should be replaced.

for i in new-config-files/*/*                  # for list of files under new directory/subdirectory
do
   [[ -f ${i/new/old} ]] && {                                     # if same file name exists under new and old directories
      awk -F\' '                                                           # use awk with ' as field delimeter
      NR==FNR {val[$4]=$6; next}                       #  for first file read (old) store field 6 in var array stub key name (field 4)
      length(val[$4]) {$6=val[$4]}                        #  for second file read replace field 6 stored for the stub name if it exists
      1                                                                          # print line
      ' ${i/new/old} OFS=\' $i > $i.tmp                  # open old file new file (with ' as delimiter) redirect output to file with tmp extension
      mv -f $i.tmp $i                                                # move tmp extension file name to original file name (clobbers file)
   }
done
                                                    \# end loop

note: make a couple of test directories to test.

1 Like

This seems to work great, thank you!

Can you explain how it's working?

Thanks for the comments. I'm not understanding how the field 4 & 6 numbers are working -- how are these counted?

Assuming I have other lines in these files, will this replace those values too, or only where I have the stub values?
I'd like to only replace the stub values in this case. The old files may have lines that also exist in the new files, whose values I don't want to transpose. It seems to only have replaced the stub values ... how?

The field divider is a single quote ('). So field 4 is the stub name. To control which stubs to update, try using a control string. ex.:

update_stubs="user:password"

for i in new-config-files/*/*
do
   [[ -f ${i/new/old} ]] && {
      awk -F\' -v stubs="$update_stubs" '
      BEGIN {
         c=split(stubs, t_array, ":");
         for (i=1; i<=c; i++) update_stubs[t_array]=t_array;
      }
      NR==FNR {if (length(update_stubs[$4])) val[$4]=$6; next;}
      length(val[$4]) {$6=val[$4];}
      1
      ' ${i/new/old} OFS=\' $i > $i.tmp
      mv -f $i.tmp $i
   }
done