Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

sed - Change characters at fixed positions 1

Status
Not open for further replies.

kasparov

Programmer
Feb 13, 2002
203
GB
I have a file with records which are nearly 500 characters long, fields are separated by the pipe character (|). I need to perform a substitution on characters at positions 417 - 421. Unfortunately there will not be any unique string here which I can substitute.

I know I could for example do something like:

's/^....... [417 times]/&UNIQUE_CHAR/'
and then use the UNIQUE_CHAR to help me confidently change the chars I want to.

But there must be a more elegant way of doing this.

I also know I can do something like 's/^.* ' to identify any character repeated any number of times. Is there any way to identify any character repeated 417 times? That would help.

Or perhaps there's a better way - I expect there is. Perhaps I shouldn't be using sed but that's what I feel most comfortable with. I don't want to write a C program or use PERL (because I don't know PERL & won't easily be able to maintain the program).

Just to help illustrate the problem. My file could look like:

| field 1| field2|field 3| x| another field|
| field 1| field2|field 3| z| another field|

What I want to change are the x & z - but in my case they are in char positions 417 - 421.

Hope this makes sense & that someone can help!

Thanks, Chris
 
Why not using awk and its substr function ?

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
Because I forgot about awk! (Been a long time since I've worked in Unix ...)

Thanks PH
 
And the sed way:
sed 's!^\(.\{417\}\).!\1X!'

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
PH - I like the look of this but I'm getting this:

sed 's!^\(.\{417\}\).!\1X!' < in_file > outfile
sed: command garbled: s!^\(.\{417\}\).!\1X!

Any idea why?
 
Any idea why?
Does your sed version use Basic Regular Expressions (BREs) or Extended Regular Expressions (EREs) ?


Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
Looking at the sed & regexp man pages I *think* only Basic.

If I run the sed command in csh (instead of ksh) I get:

sapqa:hrqadm 1% sed 's!^\(.\{417\}\).!\1X!' < in_file
0: Event not found

Does this give any clues?

Thanks
 
This ought to change characters in positions 417-421 to the string 99999

s/^\(.\{416\}\)\(.\{5\}\)/\199999/


Was this what you wanted ?
 
Thanks the the reply taupirho. Certainly that's the kind of thing I'm hoping to achieve.

Unfortunately that's still not working on my system. When I run the command you gave I get:

:ksh > sed 's/^\(.\{416\}\)\(.\{5\}\)/\199999/' < file_in | more
sed: command garbled: s/^\(.\{416\}\)\(.\{5\}\)/\199999/

Presumably I'm correct to surround the sed substitution with single quotes? If I omit them then the output is unchanged.

I also get "command garbled" if I run this command in csh.

Thanks for the help so far - it feels like it's nearly there?

Chris
 
The way I did it was to put the sed s command in a file then do

sed -fmyfile.sed input_file
 
Hi

Hopefully your [tt]sed[/tt]'s problem is only the numeric multiplier. This example excludes it :
Code:
[blue]master #[/blue] echo 1234567890 | sed 's/\(.\)/\1\n/3;s/\n\(.....\)/x/'
123x90
If the above works for you as for me, your problem should be solved as :
Code:
sed 's/\(.\)/\1\n/416;s/\n\(.....\)/199999/' /input/file

Feherke.
 
feherke - If I do this the output is not what I want:

:ksh > echo 1234567890 | sed 's/\(.\)/\1\n/3;s/\n\(.....\)/x/'
123n4567890

But if I change the \n to @ (which I can do because there will never be a '@' in the input file), then I get:

:ksh > echo 1234567890 | sed 's/\(.\)/\1@/3;s/@\(.....\)/x/'
123x90

Which means I can amend this to do what I need.

Thanks everyone for your help.

Chris
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top