Character replacement in shell scripting

Started by
7 comments, last by antiquechrono 16 years, 9 months ago
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.
Check out Drunken Brawl at http://www.angelfire.com/games6/drunken_brawl!
Advertisement
Which shell scripting language are you using?
I'm using bash:

bash-2.03$ echo $SHELL
/bin/bash
Check out Drunken Brawl at http://www.angelfire.com/games6/drunken_brawl!
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
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.
Check out Drunken Brawl at http://www.angelfire.com/games6/drunken_brawl!
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.)
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.
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.
Check out Drunken Brawl at http://www.angelfire.com/games6/drunken_brawl!
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.

This topic is closed to new replies.

Advertisement