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нιη
  • 40,939
  • 15
  • 71
  • 114
Harish a
  • 43
  • 2
  • 5
  • please also keep in mind to quote your variable that you should. read [Why does my shell script choke on whitespace or other special characters?](https://unix.stackexchange.com/q/131766/72456). – αғsнιη Dec 04 '18 at 12:17

2 Answers2

5

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

echo ${string//["$a"]}
AAA
RudiC
  • 8,889
  • 2
  • 10
  • 22
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,561
  • 18
  • 86
  • 152
  • 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