Removing unwanted symbols with sed

I would like produce

blue, green, red, yellow

from

"blue:,*green:,*red:,*yellow

I can remove the colon with

echo "blue:,*green:,*red:,*yellow" | sed 's/://g'

which gives

blue,*green,*red,*yellow

but when I try

echo "blue:,*green:,*red:,*yellow" | sed 's/://g'; 's/*//g'

I get

bash: s/*//g: No such file or directory

distro Ubuntu 18.04.1 LTS; desktop Xfce 4.12.3 (Gtk 2.24.31); kernel 4.15.0-45-generic i686 Bash version 4.4.19(1)-release; Dell Inspiron-518

Remove the single quotes in the middle:

echo "blue:,*green:,*red:,*yellow" | sed 's/://g; s/*//g'

or

echo "blue:,*green:,*red:,*yellow" | sed 's/[:*]//g'

--
The single quotes turned it into two commands:
One was:

echo "blue:,*green:,*red:,*yellow" | sed 's/://g'

and the other was:

's/*//g'
1 Like

How about (untested as I'm not at my home computer):

sed 's/^[^[:lower:]]*\|[^[:lower:]]*$//g; s/[^[:lower:]]*/, /g' file

or

sed 's/^[^[:lower:]]*\|[^[:lower:]]*$//g; s/[^[:lower:]]+/, /g' file

(possible the + needs to be escaped; can't test...)

1 Like

Gentlemen, thank you!
@Scrutinizer--your suggestions worked very well; I just need to figure out how to put spaces after the commas.
@RudiC--your second suggestion worked perfectly after escaping the "+". The first code produced a very interesting result!

, b, l, u, e, g, r, e, e, n, r, e, d, y, e, l, l, o, w,

In this case:

echo "blue:,*green:,*red:,*yellow" | sed 's/://g; s/*/ /g'

or use:

echo "blue:,*green:,*red:,*yellow" | sed 's/[:*]//g; s/,/, /g'

--
Note: \+ and \| are GNU extensions that will not work with regular sed
In regular sed, the equivalent would be something like:

sed 's/^[^[:lower:]]*//g; s/[^[:lower:]]*$//g; s/[^[:lower:]]\{1,\}/, /g'
2 Likes

@Scrutinizer--both perfect, thanks!

Maybe I did not understand again. I reread discussion several times :slight_smile:

echo "blue:,*green:,*red:,*yellow" | sed 's/:,\*/, /g'

--- Post updated at 14:35 ---

If this string in a function or in a script, example as first parameter

echo ${1//:,\*/, }
2 Likes

@nezabudka--I got your first code to work fine; I don't know how to employ the parameter thing

To all--I made this up myself, and it works! I know it's not elegant!

echo "blue:,*green:,*red:,*yellow" | sed 's/://g' | sed 's/*//g' | sed 's/,/, /g' 

I'm assuming the double slashes before the "g" are for when you aren't substituting anything.

1 Like

In command line

set -- "blue:,*green:,*red:,*yellow"
echo $1
blue:,*green:,*red:,*yellow
echo ${1//:,\*/, }
>>> blue, green, red, yellow

In the script

cat script.sh
#!/bin/bash
echo ${1//:,\*/, }

./script.sh "blue:,*green:,*red:,*yellow"
>>> blue, green, red, yellow

In the script from function

cat script.sh
#!/bin/bash
myfunc() {
    echo ${1//:,\*/, }
}
myfunc "blue:,*green:,*red:,*yellow"

./script.sh
>>> blue, green, red, yellow
1 Like

Not talking of elegance, but efficiency: Above creates three processes to execute three instances of the sed command to achieve what can be done with a single one only. Scrutinizer already showed you how to combine several sed commands into the "first non-option argument" (c.f. man sed ); you also can use several -e (expression) options on the command line:

echo "..." | sed -e's/://g' -e 's/*//g' -e 's/,/, /g'

And yes,the "double slashes" enclose the "empty string" for the replacement thus effectively removing the search pattern match.

1 Like