Reputation: 784
I want to replace special characters (regex \W) with _ (underscore) But I don't want to replace whitespace with underscore Also replace multiple consecutive special characters with single underscore
Example
String: The/Sun is red@
Output: The_Sun is red_
String: .//hack Moon
Output: _hack Moon
I have tried echo 'string' | sed 's/\W/_/g'
But it's not accurate
Upvotes: 12
Views: 9224
Reputation: 158250
Use tr
for that:
echo -n "The/Sun is red@" | tr -c -s '[:alnum:][:blank:]' '_'
[:alnum:][:blank:]
represents alphanumeric characters and whitespace-c
(or --complement
) means "use the opposite of that"-s
(or --squeeze-repeats
) to squeeze duplicate underscores into oneUpvotes: 14
Reputation: 247210
Just with bash parameter expansion, similar pattern to other answers:
shopt -s extglob
for str in "The/Sun is red@" ".//hack Moon"; do
echo "${str//+([^[:alnum:][:blank:]])/_}"
# .........^^........................^ replace all
# ...........^^.....................^ one or more
# .............^^^^^^^^^^^^^^^^^^^^^ non-alnum, non-space character
done
The_Sun is red_
_hack Moon
Upvotes: 5
Reputation: 92894
sed
approach:
s="The/Sun is red@ .//hack Moon"
sed -E 's/[^[:alnum:][:space:]]+/_/g' <<<"$s"
The_Sun is red_ _hack Moon
[^[:alnum:][:space:]]+
- match any character sequence except alphanumeric and whitespaceUpvotes: 8