2

I am trying to remove special characters (by passing them as a variable) from a string variable below command able to remove single characters not multiple?

string=#@$AAA%* 
a=#$@%*                  # Special characters which have to remove from variable
b=`echo $string|sed 's/\${a}//g'`
echo $b
αғsнιη
  • 41,407

2 Answers2

5

No need to run external commands when using recent shells' "parameter expansion":

echo ${string//["$a"]}
AAA
RudiC
  • 8,969
2

There are a few things wrong with your commands.

  • string=#@$AAA%* and a=#$@%*: here the $AAA and $@ parts are interpreted as variables. You should single-quote the strings so that they are interpreted literally.
  • For the sed part, you are asking it to replace a literal string of #$@%* in order with nothing. If you want separate characters, you'd need to use a different format, e.g. the character class [#$@%*]. However, in this case, I'd just use tr -d instead, which is much simpler.
  • Also, $(…) is preferred over backticks.
  • I'd also use a here-string (<<<) instead of an echo, just to save a few cycles.
  • I noticed that Kusalananda edited my answer to add " quotes around variables. I deliberated over this too, but figured I wouldn't because it would be simpler, and not necessary for your specific question. However, I agree that this is the "right" way to do things. I've added " quotes around the other variables and the $(…) construct; in this case they are unnecessary, but also good practice.

Hence the final commands are

string='#@$AAA%*'
a='#$@%*'
b="$(<<<"$string" tr -d "$a")"
echo "$b"
Sparhawk
  • 19,941
  • You should've left it at @Kusalananda's edit. The extra quotes you added are absolutely useless -- unlike those around "$a" and "$b", they make no difference, no matter the value of string and a. Example: s='/b * .? * * b/'; a='/*'; b=$(<<<$s tr -d "$a"); echo "$b" –  Dec 06 '18 at 00:47
  • @mosvy Yes, good point… I guess my thinking was that Kusalananda's were also not necessary in this case either. Admittedly $b may well contain whitespace in another variant, but $a almost certainly would not (at least not in a way that would break). I agree that my quotes are even more useless, but I figured I'd use them for "good practice", in a general sense… which was likely Kusalananda's thinking? I've edited the question to point this out anyway. – Sparhawk Dec 06 '18 at 00:59
  • the quotes around "$a" and "$b" are not just "good practice" (ie cargo cult). Try my example without either of them and you will see that they really make a difference. –  Dec 06 '18 at 01:02
  • @mosvy Ah yes okay. I forgot to use bash instead of my normal zsh. Yes, the * causes problems. Hopefully my edit includes this interpretation. – Sparhawk Dec 06 '18 at 01:08