[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Adding/Replacing lines with SED

Posted on 2007-10-09
16
Medium Priority
?
556 Views
Last Modified: 2013-12-04
Having trouble with getting SED to do what I want it to. The Win32 port seems to work a little differently then the linux version.

Here is the sample data:

[Registration]
User=Administrator
Number=HJ-4493MNB
NextID=67145
Check=Y

[Locations]
IconDirectory=c:\working
SoftwareDirectory=e:\build
Help=c:\working\work.hlp
RemoteConnection=RemoteDatabase
LocalLibrary=C:\working\local_library.pbl


[LocalDatabase]
DBMS=ODBC
Database=generic_data
UserID=Admin
UsePassword=Y
Check=Y


I need to change the first instance of "CHECK=Y" to "CHECK=N" and then add a line underneath that adds "IDText=Y".

This swaps the text properly, but it does it for all instances in a file, not just the first one.
sed "s/Check=Y/Check=N/" danic.ini > danic2.ini

And I can't seem to figure out the proper command to add a line after it finds the first instance of a string.

Any help would be appreciated.
0
Comment
Question by:ITD_Technician
  • 8
  • 8
16 Comments
 
LVL 5

Expert Comment

by:KirillMueller
ID: 20046639
This is a nice collection of short sed programs:

sed.sourceforge.net/sed1line.txt

The following examples are from there:

sed 's/foo/bar/'             # replaces only 1st instance in a line
sed 's/foo/bar/4'            # replaces only 4th instance in a line
sed 's/foo/bar/g'            # replaces ALL instances in a line

Perhaps your Win32 port has the 'g' option set automatically. Try

's/foo/bar/1'.

If you need to insert a new line after the replaced line, add

'\n<contents of new line>'

to the replace string, that should do the job.
0
 
LVL 5

Expert Comment

by:KirillMueller
ID: 20046756
Sorry, I was wrong about my first suggestion, this was about finding instances _in a line_.

The following sed program will do the job, I've tested it:

sed '{:start {s/^foo.*$/bar\nbaz/;t end;n;T start}};{:end n; b end}'

Synopsis: The first line that begins with foo is replaces with two lines that contain bar and baz, the rest of the file remains untouched.

The t and T commands are for flow control. The first block executes the search command and jumps to the second block upon success. The second block simply prints the input as is.

I'm curious whether there are more elegant solutions to this.
0
 

Author Comment

by:ITD_Technician
ID: 20049502
Unfortunately I don't think the linux version and the windows version see eye to eye.

This is what I tried:
sed "{:start {s/^Check=Y.*$/Check=N\nIDText=Y/;t end;n;T start}};{:end n; b end}" danic.ini > danic2.ini

Gives this error:
sed: -e expression #1, char 51: Unknown command: ``T''

I am using 3.02 if it helps
0
Veeam and MySQL: How to Perform Backup & Recovery

MySQL and the MariaDB variant are among the most used databases in Linux environments, and many critical applications support their data on them. Watch this recorded webinar to find out how Veeam Backup & Replication allows you to get consistent backups of MySQL databases.

 
LVL 5

Expert Comment

by:KirillMueller
ID: 20050673
I built the script with version 4.1.x. Could you try to replace T with b, or use a newer build of sed?
0
 

Author Comment

by:ITD_Technician
ID: 20052185
It works with the newer one except it removed all the return characters. Output looks like this:

[Registration]User=AdministratorNumber=HJ-4493MNBNextID=67145Check=NIDText=Y[Locations]IconDirectory=c:\working.....
0
 
LVL 5

Expert Comment

by:KirillMueller
ID: 20052241
What kind of line endings does your source file use? Is it CR/LF or something else?

Anyway, try the current version of sed from

http://gnuwin32.sourceforge.net/packages/sed.htm
0
 

Author Comment

by:ITD_Technician
ID: 20058334
Yeah the newest version is what wraps everything to the same line.
0
 
LVL 5

Expert Comment

by:KirillMueller
ID: 20058376
Could you post your input file to this forum, please?

Did you have a chance to look at the line endings?
0
 

Author Comment

by:ITD_Technician
ID: 20058430
It is CR/LF.
I added \r\n and that worked for the section. But I guess there needs to be a line to add this when it encounters a \n?
0
 

Author Comment

by:ITD_Technician
ID: 20058467
Sample file:
https://helpdesk.itdepartment.com/Download/Working.ini

This is not the original because it contains proprietary info
0
 
LVL 5

Expert Comment

by:KirillMueller
ID: 20058474
Is there anything different with the following command line?

sed -n "{:start {s/^Check=Y.*$/Check=N\r\nIDText=Y/;p;t end;n;b start}};{:end n;p; b end}"

(Note the -n switch, it inhibits automatic printing of the so-called "pattern space". Instead, two p commands are added to print it manually.)
0
 

Author Comment

by:ITD_Technician
ID: 20058992
It seems to have a problem with how I am writing back to the file.
This is what I have based on your new code:
sed -n "{:start {s/^Check=Y.*$/Check=N\r\nIDText=Y/;p;t end;n;b start}};{:end n;p; b end}" Working.ini > Working2.ini

If I remove "> Working2.ini"  from the list it shows up correctly in the dos window. But I need it to be written back to the file.
0
 
LVL 5

Expert Comment

by:KirillMueller
ID: 20063185
Does the following work with file redirection?

sed -n "{:start {s/^Check=Y.*$/Check=N\r\nIDText=Y\r\n/;t end;s/$/\r\n/;p;n;b start}};{:end n;s/$/\r\n/;p; b end}"

(At the end of every line, \r\n is appended.)

Check the line endings of your output file, too. (You can also post it, if you like.)
0
 

Author Comment

by:ITD_Technician
ID: 20066279
That removed Check=N and did not add IDText=Y

But it did output properly.

Sample Output:

[Registration]
User=Administrator
Number=HJ-4493MNB
NextID=67145

[Locations]
etc....
0
 

Author Comment

by:ITD_Technician
ID: 20095956
sed "1,/Check/s/^Check=Y/Check=N\r\nIDText=Y/; s/$/\r/" Working.ini > Working2.ini

This seems to do it
0
 
LVL 5

Accepted Solution

by:
KirillMueller earned 750 total points
ID: 20095986
Thanks for the info, this is indeed much more elegant than my solution.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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

This is about my first experience with programming Arduino.
Make the most of your online learning experience.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
Screencast - Getting to Know the Pipeline

865 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