So basically I have a original list of 1500 names with a 4 digit number associated with each name. I have another file which contains 200 of these 1500 names with a new 4 digit
You can generate a sed script from the update field like
sed 's:\(.*AY\)\d\+:/\1/s_.*_&_:' UPDATEFILE > SEDUPDATE.SED
Then run the generated script on the original file like:
sed -f SEDUPDATE.SED ORIGINAL_FILE
Try the following:
while read old new ; do
sed -i "s/$old \([^ ]*\)/$new \1/" original.txt
done < updated_file.txt
Warning: with the -i
option it will automatically update your original.txt
file. Don't forget to make a backup copy first.
I have upvoted @ZoltBotykai's answer but here is a minor modification which should hopefully be slightly more precise and portable.
sed 's:\(.*AY\)[0-9][0-9]*$:s_^\1[0-9]*$_&_:' updated_file.txt |
sed -f - -i original.txt
If you are on *BSD I believe you will need to add an empty argument to the -i
option in order for it to work. Remove this option while testing so you see the generated output on your screen instead of in the target file.
I tightened the regular expression somewhat and changed the \d\+
(which is a recent Perl extension, for evolutionary scales of "recent") to something which should hopefully work even on HP-UX and the like.
On the other hand, some ancient sed
implementations do not support the -f
option with a dash to read the generated script from standard input; then, you'll need to revert to storing the generated script in a temporary file.
If your actual data contains underscores, you will have to use a different separator in the generated script. The character after the s
command can be anything, but the separator must not occur (unquoted) in the substitution regex or the replacement text.