28

As we all know, sed is greatly efficient to find and replace string, for example find 'a' and replace it to 'b': sed 's/a/b/g'.

Is it possible to do this with other command or shell script instead of sed?

This is for a cropped linux systems for TV that does not have the sed command. So I have to use other commands or scripts instead of sed 's/a/b/g'. –

3
  • Actually, that is just regular expression based substitution. Any tool or language capable to handle such thing will be able to do the same, but with various syntax: $var=~s/a/b/g, gsub(/a/,"b",var), var.gsub(/a/,'b'), var.replace(/a/g,'b'), preg_replace("/a/","b",$var), regsub -all a b $var. Beside that, many tools and languages can also do plain text string replacement. So your question is somehow broad.
    – manatwork
    Oct 25, 2013 at 15:28
  • 1
    Why? What problem are you trying to solve? Oct 25, 2013 at 15:55
  • A cropped linux systems for TV have not sed command. So I has to use other command or script to instead of sed 's/a/b/g'.
    – binghenzq
    Oct 25, 2013 at 16:46

6 Answers 6

18

The classic alternative for single letter substitutions is the tr command which should be available on just about any system:

$ echo "foobar" | tr a b   
foobbr

tr is better than sed for this actually since using sed (let alone perl or awk) for single letter substitutions is like using a sledge hammer to kill a fly.

grep is not designed for this, it does not modify its input, it only searches through it.

Alternatively, you can use the substitution capabilities of some shells. Here using ksh, zsh or bash syntax:

$ foo="foobar"
$ echo "${foo//a/b}"
foobbr

We could give you more specific answers if you explained exactly what problem you are trying to solve.

2
  • Is there an option to ignore case in ${foo//a/b}? Feb 23, 2017 at 7:19
  • @AlikElzin-kilaka I'm afraid not. You'll have to use something more sophisticated like, for example: echo "$foo" | sed 's/a/b/i or give a character class: echo ${foo//[aA]/b}.
    – terdon
    Feb 23, 2017 at 10:03
14

Yes there are a variety of ways to do this. You can use awk, perl, or bash to do these activities as well. In general though sed is probably the most apropos tool for doing these types of tasks.

Examples

Say I have this sample data, in a file data.txt:

foo bar 12,300.50
foo bar 2,300.50
abc xyz 1,22,300.50

awk

$ awk '{gsub("foo", "foofoofoo", $0); print}' data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

Perl

$ perl -pe "s/foo/foofoofoo/g" data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

Inline editing

The above examples can directly modify the files too. The Perl example is trivial. Simply add the -i switch.

$ perl -pie "s/foo/foofoofoo/g" data.txt 

For awk it's a little less direct but just as effective:

$ { rm data.txt && awk '{gsub("foo", "foofoofoo", $0); print}' > data.txt; } < data.txt

This method creates a sub-shell with the braces '{ ... }` where the file is redirected into it via this:

$ { ... } < data.txt

Once the file has been redirected into the sub-shell, it's deleted and then awk is run against the contents of the file that was read into the sub-shells STDIN. This content is then processed by awk and written back out to the same file name that we just deleted, effectively replacing it.

9
  • Thanks for you answer and i will try it next workday.But i am not sure if it work because some command maybe not exist in a cropped linux systems of TV,such as 'sed'.So i still want to use command 'find','grep' and so on to solve it.
    – binghenzq
    Oct 25, 2013 at 15:47
  • @binghenzq - I've added examples that inline edit the file.
    – slm
    Nov 2, 2013 at 16:28
  • -1 I rarely downvote but in this case the point of the question seemed to be a simpler method rather than other more/equally complex and likely also dependent. If the question was just about alternatives for a full *nix machine install then I would probably +1 this otherwise good answer. Nov 2, 2013 at 16:36
  • @MichaelDurrant - I just added those elaborate inline edits b/c the OP asked for them. Also the OP set the requirement of NOT using sed not I. Sed is the appropriate tool for doing substitutions such as this, and he's obviously asking to better understand the roles of these tools, so showing someone these things though bad, are extremely education in showing them why. Too many times the ppl in the know simply say "don't do it" without explaining why, so I am. But thanks for at least leaving a comment as to why you DV.
    – slm
    Nov 2, 2013 at 16:37
  • Sure, I thought it was a great answer in all other respects. yeah I hate -1 with no explanation. Nov 2, 2013 at 16:41
4

You can use the POSIX tool ex:

ex a.txt <<eof
%s/Sunday/Monday/g
xit
eof

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

1
  • great thanks. just to add, -c flag is to execute the command when editing begins (since ex is an editor) and -s flag is either script mode disabling feedback or as some like to say slient-mode. ref for more info: ex-vi.sourceforge.net/ex.html Sep 2, 2018 at 12:07
3

If you're working with a file rather than a stream, you could use the standard text editor, ed:

printf '%s\n' ',s/a/b/g' w q | ed file.txt

This should be available on any *nix. The comma in ',s/a/b/g' tells ed to work on every line (you can also use %, which will be more familiar if you're used to vim), and the rest of it is a standard search and replace. w tells it to write (save) the file, q tells it to exit.

Note that, unlike sed's -i option (and similar options in other tools), this actually does edit the file in-place rather than cheating with temporary files.

I don't think it's possible to get this working with streams, but then I don't really know much about ed and I wouldn't be surprised if it actually does have that capability (the unix philosophy being what it is).

2

Using the ancestor command (in which -s means quiet (silent) and the comma before the commands means execute on all lines):

Just printing on STDOUT:

ed -s file <<!
,s/a/b/g
,p
q
!

replacing in-place:

ed -s file <<!
,s/a/b/g
w
q
!
0

If you are using linux OS eg Ubuntu Desktop like me, you will have python installed.

With python, we can do text replacing as below

result=$(python << EOT
s = '$your_string_in_shell_script'
r = s.replace('text to replace', 'replaced by this text')
print(r)
EOT)

echo $result

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .