Bash – Piping bash string manipulation

bashstringvariable substitution

I've read some other piping bash string manipulation questions but they seem to be specialized applications.

Essentially, is there a way to do the below simpler?

instead of

$ string='hello world'; string2="${string// /_}"; echo "${string2^^}"
HELLO_WORLD

something like

$ echo 'hello world' | $"{-// /_}" | "${ -^^}"
HELLO_WORLD

Edit
I'm interested in staying within bash manipulations if possible to maintain speed (as opposed to sed/awk which have a tendency to greatly slow down my scripts)

Edit2: @jimmij

I like the second example and led me to making a function.

bash_m() { { read x; echo "${x// /_}"; } | { read x; echo "${x^^}"; }; }
echo hello world | bash_m
HELLO_WORLD

Best Answer

What jimmij said. His last example is the closest you can get to what you're attempting in your piped expression.

Here's a variant on that theme:

echo 'hello world'|echo $(read s;s=${s^^};echo ${s// /_})

I'd be inclined to use tr, as it's quite fast.

echo 'hello world'|tr ' [:lower:]' '_[:upper:]'

I suppose it's a shame that bash doesn't permit nested parameter expansion; OTOH, use of such nested expressions could easily lead to code that's painful to read. Unless you really need things to run as fast as possible it's better to write code that's easy to read, understand and maintain, rather than clever-looking code that's a PITA to debug. And if you really do need things to be done at top speed you should be using compiled code, not a script.

Related Question