If, on the off-chance, you're just trying to handle quotes for reuse ion the shell, then you can do this without removing them, and it's dead simple, too:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
That function shell quotes any arg array you hand it and increments its output per iterable argument.
Here it is with a few args:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
OUTPUT
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
That output is from dash which typically safe-quotes single-quoted output like '"'"'. bash would do '\''.
Replacing a selection of single, non-whitespace, non-null bytes with another single byte can likely be done quickest in any POSIX shell with $IFS and $*.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
OUTPUT
"some ""crazy """"""""string ""here
There I just printf it so you can see it, but of course, if I had done:
var="$*"
...rather than the printf command $var's value would be what you see in the output there.
When I set -f I instruct the shell not to glob - in case the string contains characters that could be construed as glob patterns. I do this because the shells parser expands glob patterns after it performs field splitting on variables. globbing can be re-enabled like set +f. In general - in scripts - I find it useful to set my bang like:
#!/usr/bin/sh -f
And then to explicitly enable globbing with set +f on whatever line I might want it.
Field splitting occurs based on the characters in $IFS.
There are two kinds of $IFS values - $IFS whitespace and $IFS non-whitespace. $IFS whitespace (space, tab, newline) delimited fields are specified to elide by sequence to a single field (or none at all if they do not precede something else) - so...
IFS=\ ; var=' '; printf '<%s>' $var
<>
But all others are specified to evaluate to a single field per occurrence - they are not truncated.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
All variable expansions are, by default, $IFS delimited data arrays - they split out to separate fields according to $IFS. When you "-quote one you override that array property and evaluate it as a single string.
So when I do...
IFS=\"\'\`; set -- $var
I am setting the shell's argument array to the many $IFS delimited fields generated by $var's expansion. When it is expanded its constituent values for the characters contained in $IFS are lost - they are only field separators now - they are \0NUL.
"$*" - like other double-quoted variable-expansions - also overrides the field-splitting qualities of $IFS. But, in addition, it substitutes the first byte in $IFS for each delimited field in "$@". So because " was the first value in $IFS all subsequent delimiters become " in "$*". And the " needn't be in $IFS when you split it, either. You could alter $IFS after set -- $args to another value entirely and its new first byte would then show up for the field delimiters in "$*". What's more, you can remove all traces of them entirely like:
set -- $var; IFS=; printf %s "$*"
OUTPUT
some crazy string here
tr. BASH's PE is good but tr is much faster in this case. e.g.echo "$OUTPUT" | tr -dc '[[:alpha:]]'since you want to have alphanumerics onlyecho "$OUTPUT". Or better:printf "%s\n" "$OUTPUT". (What happens whenOUTPUT="-n"?)