sed - print only the chars that match a given set in a string

For a given string that may contain any ASCII chars, i.e. that matches .*,
find and print only the chars that are in a given subset.

The string could also have numbers, uppercase, special chars such as ~!@#$%^&*(){}\", whatever a user could type in
without going esoteric

For simplicity take for example a string like:

zabacaaszdeaazfagaaahaaaiazakalmnzzopaaqzrastazauzazvwzaxyz

and a subset such as [a|z].

[1] What we want is to print out just all the 'a' and 'z' chars.

I can do this with grep:

 echo zabacaaszdeaazfagaaahaaaiazakalmnzzopaaqzrastazauzazvwzaxyz|grep -oz '[a|z]'

or, essentially the same thing

echo zabacaaszdeaazfagaaahaaaiazakalmnzzopaaqzrastazauzazvwzaxyz|grep -ozE 'a|z'

which yields: zaaaazaazaaaaaaaazaazzaazaazazazzaz

(and could perl it just as easy as well although I have not even tried)

Essentially I want the complementary set of what we get when doing:

[2] Find and print only chars that are neither 'a' or 'z'

which in sed is trivial ...

 echo zabacaaszdeaazfagaaahaaaiazakalmnzzopaaqzrastazauzazvwzaxyz|sed -e 's/[a|z]*//g'

So, how can we do [1] above just with sed commands?

(I gather that this must also be trivial, but I fail to come up with a sed solution and request you wizardry once again :wink:

Thanks in advance

Robert Nader

------ Post updated at 03:57 PM ------

I just thought about the complementary ...

echo zabacaaszdeaazfagaaahaaaiazakalmnzzopaaqzrastazauzazvwzaxyz|sed -e 's/[^a&^z]*//g'

# I mean ...

echo zabacaaszdeaazfagaaahaaaiazakalmnzzopaaqzrastazauzazvwzaxyz|sed -e 's/[^(az)]*//g'

It was too trivial after all, should probably delete this post!

Sorry for the bother! :wink:

As MadeInGermany (thanks!) pointed out, the correct form is just
negating the pattern with:

s/[^az]//g
  1. A [ ] character set has its own syntax.
  2. [a|z] matches the three enclosed characters.
  3. [az] matches the two characters.
  4. [a-z] matches the range a thru z.

If the first character is a ^ then it negates the following character and -ranges.
Let sed delete all but a z

sed 's/[^az]//g'

You can also use tr for it

tr -dc 'az'
1 Like