LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-07-2009, 07:50 PM   #1
pobrika
Member
 
Registered: Jan 2008
Location: Bournemouth, UK
Distribution: Mint, #!, Fedora, Redhat, Centos
Posts: 70

Rep: Reputation: 18
sed to change character in text file only once.


Ok I have been all over the net and read books and still can't figure this one out, please someone show me the light.

I have a script that looks like:
Code:
cat servers.txt
trivia:P:N
trivia:D:N
tucana:P:Y
vesta:D:Y
victor:D:Y
vulcan:D:Y
wn-nzp-pin-1:P:Y
wnsf2sc-pvg:P:N
wnsf2sc0-pvg:P:N
wnsf2sc1-pvg:P:N
wnt3pp1:P:N
I want to be able to find the lines that matches my input and change the N to a Y, but only for the lines that matches the name and not any other N's
My problem is the line does not always contain a P as it can be a D as well so my matching did not work.

If my script issues the name $1=triva the lines will change to:
Code:
trivia:P:Y
trivia:D:Y
I have the following code so far but as you can see it does not change the D's
Code:
sed -i 's/trivia:P:Y/trivia:P:N/g' servers.txt
Thanks

*** UPDATE ***

should I be using a method as follows? I am still stuck on the changing all instances though.
Code:
$1=server

sed -i 's/$server1:P:Y/$server:P:N/g' server.txt
sed -i 's/$server1:D:Y/$server:D:N/g' server.txt

Last edited by pobrika; 09-07-2009 at 08:18 PM. Reason: Updated with new Idea?
 
Old 09-07-2009, 10:46 PM   #2
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,790

Rep: Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653
Hi pobrika,

Here's an example you can work from:

Code:
#!/bin/bash

SERVER=$1

if [ -z $SERVER ]
then
        echo "Usage: $0 servername"
        exit
fi

sed -i "s/\(${SERVER}\:[PD]\:\)N/\1Y/" servers.txt
Notes:
Sed requires double quotes to interpret variables inside the regex
Colons need to be escaped
'$' will not be interpreted on the RHS so use backreference - '( )' / '\1'
Use '[]' to define a set or range to match

cheers,

kbp
 
Old 09-07-2009, 11:04 PM   #3
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Code:
name="trivia"
awk -v name=$name -F":" '$1~name&&$NF=="N"{$NF="Y"}1' file > temp
mv temp file
 
Old 09-08-2009, 12:13 AM   #4
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by kbp View Post
Code:
#!/bin/bash

SERVER=$1

if [ -z $SERVER ]
then
        echo "Usage: $0 servername"
        exit
fi

sed -i "s/\(${SERVER}\:[PD]\:\)N/\1Y/" servers.txt
Another way to do it, i.e. without having to concern yourself with the rest of the line is to do this:
Code:
sed -i "/$SERVER/s/:N$/:Y/" servers.txt
Two things to watch out for here. The first is the name of the server. If for some reason you're going to use a path, change all / to something else, e.g. @. The second thing is the -i option. This is very handy, however, you should skip it initially and preview using less to make sure you don't permanently ruin your file (or use something like -i.bak.)
Kevin Barry
 
Old 09-08-2009, 06:40 AM   #5
pobrika
Member
 
Registered: Jan 2008
Location: Bournemouth, UK
Distribution: Mint, #!, Fedora, Redhat, Centos
Posts: 70

Original Poster
Rep: Reputation: 18
Cheers everyone that is exactly what I was looking for I knew there must be a one liner for the sed command, annoyed with myself for not being able to find the answer on my own

I'll do some playing around and see which method works best in my script.

 
Old 09-08-2009, 10:30 AM   #6
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Here is a good place to learn more complex things:
http://www.grymoire.com/Unix/Sed.html

Kevin Barry
 
Old 09-08-2009, 11:49 PM   #7
pobrika
Member
 
Registered: Jan 2008
Location: Bournemouth, UK
Distribution: Mint, #!, Fedora, Redhat, Centos
Posts: 70

Original Poster
Rep: Reputation: 18
Smile

Just a follow up to say I managed to get my script to work, the only problems I had was the testing was done on my trusty rhel4 server and the script would not run on a solaris 8 platform.
Turned out the -i option did not work.
I ended up using:

Code:
sed "s/\(${SERVER}\:[PD]\:\)N/\1Y/" /usr/local/bin/servers.txt > /tmp/servers.txt
mv /tmp/servers.txt /usr/local/bin/servers.txt
I hate writing files out and back in as it is "messy" but it works.
 
Old 09-09-2009, 07:43 AM   #8
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by pobrika View Post
Just a follow up to say I managed to get my script to work, the only problems I had was the testing was done on my trusty rhel4 server and the script would not run on a solaris 8 platform.
Turned out the -i option did not work.
I ended up using:

Code:
sed "s/\(${SERVER}\:[PD]\:\)N/\1Y/" /usr/local/bin/servers.txt > /tmp/servers.txt
mv /tmp/servers.txt /usr/local/bin/servers.txt
I hate writing files out and back in as it is "messy" but it works.
Not only that, if the file has multiple links (i.e. hard linked) they might not keep pointing to the same file unless you do this instead of mv:
Code:
cat /tmp/servers.txt > /usr/local/bin/servers.txt
rm /tmp/servers.txt
Also, if this is in a script you might want to use mktemp in case it happens to get called twice concurrently. That way you won't overwrite something in progress.
Kevin Barry
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash scripting: parsing a text file character-by-character Completely Clueless Programming 13 08-12-2009 09:07 AM
using sed to replace text on one line in a text file vo1pwf Linux - Newbie 5 06-24-2009 07:54 AM
How to store text(strings) in a 2D character array reading from a text file(C++) bewidankit Programming 3 02-14-2008 07:08 AM
how to change test sizze or character size in run level 3 in text mode? betrussell23 Linux - Newbie 1 10-13-2006 04:23 AM
SED - display text on specific line of text file 3saul Linux - Software 3 12-29-2005 04:32 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:22 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration