ITD_Technician
asked on
Adding/Replacing lines with SED
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=RemoteDat abase
LocalLibrary=C:\working\lo cal_librar y.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.
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=RemoteDat
LocalLibrary=C:\working\lo
[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.
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.
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.
ASKER
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\nID Text=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
This is what I tried:
sed "{:start {s/^Check=Y.*$/Check=N\nID
Gives this error:
sed: -e expression #1, char 51: Unknown command: ``T''
I am using 3.02 if it helps
I built the script with version 4.1.x. Could you try to replace T with b, or use a newer build of sed?
ASKER
It works with the newer one except it removed all the return characters. Output looks like this:
[Registration]User=Adminis tratorNumb er=HJ-4493 MNBNextID= 67145Check =NIDText=Y [Locations ]IconDirec tory=c:\wo rking.....
[Registration]User=Adminis
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
Anyway, try the current version of sed from
http://gnuwin32.sourceforge.net/packages/sed.htm
ASKER
Yeah the newest version is what wraps everything to the same line.
Could you post your input file to this forum, please?
Did you have a chance to look at the line endings?
Did you have a chance to look at the line endings?
ASKER
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?
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?
ASKER
Sample file:
https://helpdesk.itdepartment.com/Download/Working.ini
This is not the original because it contains proprietary info
https://helpdesk.itdepartment.com/Download/Working.ini
This is not the original because it contains proprietary info
Is there anything different with the following command line?
sed -n "{:start {s/^Check=Y.*$/Check=N\r\n IDText=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.)
sed -n "{:start {s/^Check=Y.*$/Check=N\r\n
(Note the -n switch, it inhibits automatic printing of the so-called "pattern space". Instead, two p commands are added to print it manually.)
ASKER
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\n IDText=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.
This is what I have based on your new code:
sed -n "{:start {s/^Check=Y.*$/Check=N\r\n
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.
Does the following work with file redirection?
sed -n "{:start {s/^Check=Y.*$/Check=N\r\n IDText=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.)
sed -n "{:start {s/^Check=Y.*$/Check=N\r\n
(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.)
ASKER
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....
But it did output properly.
Sample Output:
[Registration]
User=Administrator
Number=HJ-4493MNB
NextID=67145
[Locations]
etc....
ASKER
sed "1,/Check/s/^Check=Y/Check =N\r\nIDTe xt=Y/; s/$/\r/" Working.ini > Working2.ini
This seems to do it
This seems to do it
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
sed.sourceforge.net/sed1li
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.