Asterdahl
Asterdahl

Reputation: 85

Find and Replace Incrementally Across Multiple Files - Bash

I apologize in advance if this belongs in SuperUser, I always have a hard time discerning whether these scripting in bash questions are better placed here or there. Currently I know how to find and replace strings in multiple files, and how to find and replace strings within a single file incrementally from searching for a solution to this issue, but how to combine them eludes me.

Here's the explanation:

Here's what I want to do:

Clarifications:

Upvotes: 0

Views: 418

Answers (2)

Asterdahl
Asterdahl

Reputation: 85

@Carl.Anderson got me started on the right track and after a little tweaking, I ended up implementing his solution but with some syntax tweaks.

First of all, this solution only works if all of your files are located in the same directory. I'm sure anyone with even slightly more experience with UNIX than me could modify this to work recursively, but here goes:

First I ran:

-hr "MessageKey" . | sort -u | awk '{ printf("%s:xx.aaa%04d\n", $2, ++i); }' > MessageKey

This command was used to create a find and replace map file called "MessageKey."

The contents of which looked like:

In.Rtilyd1:aa.xxx0087
In.Rzueei1:aa.xxx0088
In.Sfricf1:aa.xxx0089
In.Slooac1:aa.xxx0090
etc...

Then I ran:

MessageKey | while IFS=: read old new; do sed -i -e "s/MessageKey $old/MessageKey $new/" *Data ; done

I had to use IFS=: (or I could have alternatively find and replaced all : in the map file with a space, but the former seemed easier.

Anyway, in the end this worked! Thanks Carl for pointing me in the right direction.

Upvotes: 0

carl.anderson
carl.anderson

Reputation: 1118

I would approach this by creating a mapping from old key to new and dumping that into a temp file.

grep MessageKey *.data \
  | sort -u \
  | awk '{ printf("%s:xx.aaa%04d\n", $1, ++i); }' \
  > /tmp/key_mapping

From there I would confirm that the file looks right before I applied the mapping using sed to the files.

cat /tmp/key_mapping \
  | while read old new; do
      sed -i -e "s:MessageKey $old:MessageKey $new:" * \
    done

This will probably work for you, but it's neither elegant or efficient. This is how I would do it if I were only going to run it once. If I were going to run this regularly and efficiency mattered, I would probably write a quick python script.

Upvotes: 1

Related Questions