Line match and replace, using sed or awk

Posted on 2003-02-23
Medium Priority
Last Modified: 2013-12-26
I'm making a ksh script that iterates through a file and replaces a string of words with another string of words.  I can read the file one line at a time, but don't have the code that will replace the line (made up of words and tabs) with another sequence of words.

To be more specific, the script is to change an existing emailaddress with a new one, based on the original user-emailaddress pair.  Here is a sample of my code - it obviously doesn't work but you may be able to see what I'm trying to do...

cat $emailfile | sed s/"$user\t$emailaddress"/"$user\t$newemailaddress"/ > $emailfile

cat $emailfile | awk '{
if ("$1" == "$user") && ("$2" == "$emailaddress")
  print "$user\t$newemailaddress"
  print "$user\t$emailaddres"
}' > $emailfile

It seems rather simple, but I just can't seem to get it to work with more than one word.  I have tried many variations on the code and it either does nothing to the file, replaces the line with only the username, or wipes the entire file clean.  Any suggestions will be greatly appreciated...
Question by:JosipKulundzic
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2

Expert Comment

ID: 8006666
Can you provide some example input as well as what you would like the result to look like?

Btw, if your file is getting wiped out, it's because you can't write to the same file you're reading from; the > redirector truncates it before it's read.  Output to a different filename (and then rename it to the original filename if you must use the same filename).

Expert Comment

ID: 8009397
Try something along the following lines:

cat $emailfile | grep -v "^\#" | sed '/^$/d'                   > $$tmp

for UNAME in `cat $$tmp`

#break line up and assign to appropriate variables eg

user=`echo $UNAME | cut -d: -f1`
emailaddress=`echo $UNAME | cut -d: -f2`

sed s/"$user\t$emailaddress"/"$user\t$newemailaddress"/ >> $newemailfile


Author Comment

ID: 8012909
The original file will contain the following input:

user1        user1@fakemail.com
user2        user2@fakemail.com
user3        user3@fakemail.com
(Words are Tab seperated "\t")

If I wanted to update a line, it would match the user-address pair and replace it with another - so the resulting file will look like this...

user1        user1@fakemail.com
differentuser2        newuser2@newfakemail.com
user3        user3@fakemail.com

CarolAnn, as for your comment, I beleive the same problem still exists - the line of code that will cause problems is: sed s/"$user\t$emailaddress"/"$user\t$newemailaddress"/ >> $newemailfile.

Your code is (functionaly) no different from the example I gave to begin with:
cat $emailfile | sed s/"$user\t$emailaddress"/"$user\t$newemailaddress"/ > $emailfile:  It's the TAB between the words that is causing problems, sed doesn't seem to be able to parse multiple words. As I said before - it seems simple enough but its becoming a real pain...
Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf


Expert Comment

ID: 8014106
OK, I think I see where you're going.  So you only need to replace one line per invocation of the script?

This should do that:




exec awk 'BEGIN {FS="        "; OFS=FS}
        if ($1 == user && $2 == mail) {
                $1 = newuser
                $2 = newmail
}' user="$user" mail="$mail" newuser="$newuser" newmail="$newmail"

$ sh addr.sh < input4
user1   user1@fakemail.com
34234234        sdfdsfdsf
user3   user3@fakemail.com

If you wanted to make it more easily re-usable you could delete those variable assignments at the top and pass them in the environment when you run it instead.

Expert Comment

ID: 8015335
Try replacing the tabs with colons. In my example the line is broken into variables which have been colon separated. Obviously you would have to change the file you read in to contain colons instead of tabs. Then you could  use the command

s/"$user$emailaddress"/"$user$newemailaddress"/ > $emailfile

Is this possible ?

Carol Ann

Accepted Solution

CarolAnn earned 100 total points
ID: 8015397
In fact you don't even have to search and replace. You could write out a new file.

Author Comment

ID: 8020668
Hi guys, I've actually come up with a simpler solution that acheives the same outcome.

Just cat the file then
 | grep -v -x "$user    $emailaddress"
(I've only just discovered the -x switch, which matches all the characters exactly in the string with what's on one line)

This will create a file without that line.  Then all I do is append >> the new line to the file - couldn't be any simpler!

Thankyou all for your time and effort.

Author Comment

ID: 8345980
Close enough to the solution, though not very descriptive.  I would like to evenly share the points between you two for both your efforts, but dunno if that is possible...

please excuse the lateness of the reply.

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question