From: Ed Morton on
On 3/3/2010 2:26 AM, Teemu Likonen wrote:
> * 2010-03-02 23:17 (-0600), Ed Morton wrote:
>
>> Doesn't help, it's not a simple string replacement:
>>
>> $ foo=something
>> $ bar=something
>> $ echo ${foo/$bar/else}
>> else
>> $ bar=somestring
>> $ echo ${foo/$bar/else}
>> something
>> $ bar=so*ng
>> $ echo ${foo/$bar/else}
>> else
>
> It think it does help. It's a simpler replacement than regexps.

Looks like it does help when quoted properly as pk pointed out:

echo "${foo/"$bar"/else}"

So I guess the proposed solution for the case in point of replacing all
occurrences of some string contained in variable "$foo" with another string
"bar" in a text file using this approach would be:

while IFS= read -r line; do
printf "%s\n" "${line/"$foo"/bar}"
done < file > newfile

Right? Any problems with that approach?

It's not enormously briefer than:

awk -v old="$foo" 'strt=index($0,old) {
$0 = substr($0,1,strt-1) bar substr($0,strt+length(old))
}1' file > newfile

of course, but I think a bit clearer.

Ed.


From: pk on
Ed Morton wrote:

> So I guess the proposed solution for the case in point of replacing all
> occurrences of some string contained in variable "$foo" with another
> string "bar" in a text file using this approach would be:
>
> while IFS= read -r line; do
> printf "%s\n" "${line/"$foo"/bar}"
> done < file > newfile
>
> Right? Any problems with that approach?

The only issue is that the ${line/foo/bar} expansion is not standard,
although I believe most shells support it these days (bash, ksh and zsh
surely do - at least the versions that come with RedHat, which is the only
system I could test on right now).

On a related note, since you mentioned Perl previously, what Perl does
(AFAIK; there may be more) is just to provide automated escaping of the
pattern using the special \Q...\E modifiers, ie nothing more than what could
be done manually in any tool/language that does not have that feature
(although accurately doing the same by hand for Perl complex regexps would
admittedly be hard).

For example:

$ perl -e '$pat="[123[:alpha:]]foo.*bar(abc)?z{4}"; print "\Q$pat\E\n";'
\[123\[\:alpha\:\]\]foo\.\*bar\(abc\)\?z\{4\}