• Advertisement
Sign in to follow this  

Character replacement in shell scripting

This topic is 3861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been trying to figure out how to replace a single character in a string in shell scripting. So far, the only way I was able to figure this out was to use some nasty string concatenation: newtext="${oldtext:0:$count+189}${index:$count:1}${oldtext:$count+190}" This replaces characters in a line (starting with the 190th) with the nth character of an index. "count" counts from left to right in a loop, replace characters in a line of text. This exists within a loop where count iterates through the string which is replacing sequential characters in oldtext. I'm wondering if there's a way to do something equlivalent to: newtext[count+190] = index[count], but lots of google searching reveals nothing. I'm also unsure as to why $count+190 works in the code above, and why $count+191 is not the correct "solution" to this problem. Thanks a ton in advance. I'm not as bad of a programmer as I may seem, I just don't use shell scripting much.

Share this post


Link to post
Share on other sites
Advertisement
To do string replacement you should use the sed command and regular expressions, it just makes life easy. In example to replace a single character in a string the following should work to replace the h in hello.

blah="hello"

echo $blah | sed 's/h//'

That is a very basic example and may not be exactly what you are looking for so you could try here for additional reference http://www.grymoire.com/Unix/Sed.html#uh-12

Share this post


Link to post
Share on other sites
I've used sed before for search and replace, but not for replacing a fixed position in a line.

I'm wondering if it's possible to do something like:

sed -e 's/.{10}./.{10}x/'

I want to, in this example, leave 10 characters unchanged and change the 11th to an x. I know that this will match the first occurrence, so if I can figure out how to make it accept this sort of regular expression, I could pull it off.

This command, however, seems to do absolutely nothing. I'm unsure of how kleene closure works in the replacement string.

Share this post


Link to post
Share on other sites
Quote:
Original post by gamechampionx
This command, however, seems to do absolutely nothing. I'm unsure of how kleene closure works in the replacement string.


It doesn't, AFAIK. Try capturing the text before the replacement and using a backreference (i.e. \1) instead: 's/\(.{10}\)./\1x/'. (Not sure if 'sed's syntax for regular expressions wants the parentheses escaped or not.)

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by gamechampionx
This command, however, seems to do absolutely nothing. I'm unsure of how kleene closure works in the replacement string.


It doesn't, AFAIK. Try capturing the text before the replacement and using a backreference (i.e. \1) instead: 's/\(.{10}\)./\1x/'. (Not sure if 'sed's syntax for regular expressions wants the parentheses escaped or not.)


You might also try using 'cut'.

Quote:

I'm also unsure as to why $count+190 works in the code above, and why $count+191 is not the correct "solution" to this problem.


I assume that the ranges are exclusive of the last element, so that {oldtext:0:$count+189} is $count + 189 characters, with indices 0 through $count + 188, inclusive. Thus the character you replace is the one with index $count + 189, and the next one is $count + 190.

Share this post


Link to post
Share on other sites
OK, I forgot that the indexing was indexed 0-based while my results in the text in the text file was 1-based.

Since the regex thing doesn't work, sed is completely out of the question. I need to make this work without a consistent pattern preceeding the first character replacement position.

I'll take a look to see if I can use cut so solve this problem - it actually seems related to my specific issue.

Share this post


Link to post
Share on other sites
Hello again if you want to replace a single character at a position then this is even easier than before.

Let us pretend that we have the following string...

blah="asdfghjkl"

Let us also pretend that we want to replace the fourth character (the f) with a Z. The following sed expression will do exactly what we want.

echo $blah | sed 's/./Z/4'

The output will be the following...

asdZghjkl

As a suggestion however, if you are parsing large ammounts of text I would suggest useing perl.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement