kheraud
kheraud

Reputation: 5288

Bash- How to convert non-alphanumerical character to "_"

I am trying to store user input in a variable and clean that variable in order to keep only alphanumerical caract + some others (I mean [a-zA-Z0-9-_]).

I tried using this but it isn't exhaustive :

SERVICE_NAME=$(echo $SERVICE_NAME | tr A-Z a-z | tr ' ' _ | tr \' _ | tr \" _)

Do you have some help for this?

Upvotes: 11

Views: 5423

Answers (4)

user unknown
user unknown

Reputation: 36229

Bash's string substitution is a fine thing: ${var//pat/rep}

val='Foo$%!*@BAR###baZ'
echo ${val//[^a-zA-Z_-]/_}
Foo_____BAR___baZ

A small explanation: The slash introduces a search/replace, a little like in sed (where it just delimits patterns). But you use a single slash for one replacement:

val='Foo$%!*@BAR###baZ'
echo ${val/[^a-zA-Z_-]/_}
Foo_%!*@BAR###baZ

Two slashes // mean replace all. Uncommon, but it has some logic, multiple slashes to mean multiple replace (please excuse my poor English).

And note how the $ is separated from the variable, but it is hard to modify a literal constant this way (which would be nice for testing). Modifying $1 isn't a no-brainer as well, afaik.

Upvotes: 17

clt60
clt60

Reputation: 63902

perl way:

perl -ple 's/[^\w\-]/_/g'

pure bash way

a='foo-BAR_123,.:goo'
echo ${a//[^[:alnum:]-]/_}

produces:

foo-BAR_123___goo

Upvotes: 0

anubhava
anubhava

Reputation: 785098

I believe it can all be done in 1 single sed command like this:

echo 'Foo$%!*@BAR###baZ' | sed -e 's/[A-Z]/\L&/g' -e 's/[^a-z0-9\-]/_/g'

OUTPUT

foo_____bar___baz

Upvotes: 1

Steve Prentice
Steve Prentice

Reputation: 23514

$ echo 'asd!@QCW@@D' | tr A-Z a-z | sed -e 's/[^a-zA-Z0-9\-]/_/g'
asd__qcw__d

I would use sed for this and use the ^ (not) operator in your set of valid characters and replace everything else with an underscore. The above shows the syntax with the output.

And, as a bonus, if you want to replace a run of invalid characters with one underscore, just add + to your regular expression (and use the -r switch to sed to make it use extended regular expressions:

$ echo 'asd!@QCW@@D' | tr A-Z a-z | sed -r 's/[^a-zA-Z0-9\-]+/_/g'
asd_qcw_d

Upvotes: 11

Related Questions