Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

tr is great for translating a set of characters to another set of characters. Sometimes, I want to translate a set of characters to a set of strings, e.g. all < and > to &lt; and &gt;.

Pulling out sed/awk/perl for such a task seems unnecessary. Is there another common command that can accomplish simple substitutions?

share|improve this question

3 Answers 3

I don't know which shell you are using, but chances are tr is not a builtin. It's sure not for me in bash or zsh :) Try running type tr to see for yourself.

In all likelyhood, sed is the right tool for the job. It's what it was made for. As appropriate perl and awk too.

If you have very simple cases and if you are working with a string variable instead of a pipeline, you might get away with a real builtin such as using bash's string search and replace on a variable.

string="Stuf with <tag> in it."
escaped=${string//</&lt;}
escaped=${escaped//>/&gt;}
echo $escaped
share|improve this answer
    
I've fixed the terminology :) –  Tim N Jul 8 '11 at 14:24

Replacing multiple strings with another set of multiple strings becomes messy if you want to use standard parameter handling. Usually, commands take a set of atomic parameters, and then a set of atomic arguments, and the sequence doesn't matter other than that arguments come after parameters (separated by -- if ambiguous). How would you construct the synopsis in this case?

Here's a simple function which should do the job for simple replacements:

$ trs() {
    local string=$1
    shift
    for replacement in "$@"
    do
        string="$(sed -e "s/$replacement/g" <<< "$string")"
    done
    printf "$string"
}
$ trs '1 2 3' '1/foo' '2 3/bar baz'
foo bar baz

Alternatively you could work with pairs of parameters:

$ trs() {
    local string=$1
    shift
    while [ $# -gt 0 ]
    do
        string="$(sed -e "s/$1/$2/g" <<< "$string")"
        shift 2
    done
    printf "$string"
}
$ trs '1 2 3' 1 foo '2 3' 'bar baz'
foo bar baz
share|improve this answer
    
These are nice functions. I hoped to find one that is readily available on a foreign system. –  Tim N Jul 8 '11 at 14:48
    
By the way, these wouldn't handle strings containing special strings like \? or &. –  Tim N Jul 8 '11 at 14:54
1  
@Tim Nordenfur: If you only want to replace literals, you should escape it, yes. This approach allows for regular expressions, which of course is another can of worms. –  l0b0 Jul 8 '11 at 15:20

sed can be scary, but simple character to string substitution with sed isn't really too bad.

To substitute x with the string bar, do:

{something-that-outputs-something-on-stdout} | sed -e 's/x/bar/g'

if it's a file you're wanting to process, you can use:

sed -e '/s/x/bar/g' {filename}

(The "g" at the end means "global" which means substitute all occurrences in the line and not just the first one found)

share|improve this answer
1  
I'm not scared of sed; I embrace it. The reason I'm asking is that using simpler tools seems to be generally encouraged, e.g. not sedding when you can cut. –  Tim N Jul 8 '11 at 14:44
1  
how about not cating when you can just use sed –  xenoterracide Jul 8 '11 at 15:44
    
@xenoterracide: Good point, edited answer. –  ultrasawblade Jul 8 '11 at 16:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.