Link to home
Start Free TrialLog in
Avatar of Michael Smith
Michael SmithFlag for Ireland

asked on

Find and replace many occurrences of a file with a new file.

Ubuntu 16 server- no GUI available.

I have a small config file called config.xml

I have this folder structure..

Folder A with 100's of subfolders - each subfolder contains a config.xml

I'm looking for a command to find and replace all files called config.xml with my new modified master config.xml file....

thanks for looking
Mike
ASKER CERTIFIED SOLUTION
Avatar of David Favor
David Favor
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Are all config.xml files the same?
An option is to get a diff between the old and the new, and then use patch to apply the difference/fix ...



You could use find
date=$(date +"%Y%m%b")
location='/path/to/config.xml'
find /path -name "config.xml'
You could use the suggestion David provider to backup the current file before updating it with the new one.
..
arnold's suggestion is safer.

Maybe even go so far as to rename the original file to config.xml.save.$date to keep a backup copy.
here is the full code,
#!/bin/bash

marker=$(date +"%Y%m%d")
Location_of_new_file='/path/to/new/file/config.xml'
location_of_search="/path/to/base/of/search"
find  $location_of_search -name "config.xml" | while read file_name; do
echo "Found $file_name:"
file_copy="$(dirname $file_name)/$marker-config.xml"
mv "$file_name" "$file_copy"
echo "Created $file_copy"
/bin/cp -f $Location_of_new_file $file_name
chmod 644 $file_name #set permissions
chown user:group $file_name #set ownership

done

Open in new window

If it really is the case that all config.xml files are the same, might you like to  consider making them all symbolic links to the master?
In the above scripts, replace cp -a or cp -f with ln -sf.
You would get the benefit of at least 3 advantages of using symbolic links:
  1. Only one file to update next time
  2. Only need permissions of master to be right
  3. Only need group / owner of master to be right
To be really sure of not clobbering anything: as you walk through the tree, diff each file against a copy of the original. Only if the 2 match, replace the target file with a symbolic link to the new master.
Will post an attempt at a script next
I have tested this with sub-directories a, b & c where b had a different file. After correcting, a re-run finished the job
#!/bin/sh
#set -x # Un-comment to debug
# Run this script *before* changing config.xml
# (or put the old one back temporarily)

# This script exits if it finds a config.xml which differs from the master.
# If that happens, correct the problem and re-run the script.
# If you do need the config.xml to be different,
# rename it temporarily so it is not found by this script again:
# be sure to rename it back afterwards.

set -e # Stop on any error

cd A # Replace A with your actual path

# "-type f" in the find command below stops you finding symlinks
# (e.g. created in previous runs of this script)
# -mindepth 2 stops you finding ./config.xml
find . -mindepth 2 -type f -name config.xml | while read F; do
  #echo "Processing $F" # Un-comment for verbode output
  diff $F . || { echo "diffs detected in $F: stopping" >&2; exit 1; }
  /bin/rm -f $F # /bin/rm to defeat any rm shennanagins in the environment
  /bin/ln -s $PWD/config.xml $F
done

Open in new window

This script creates symbolic links as absolute paths
This script will not work if any of your directory names have spaces in them (fails doing while read).