BASH: How can I combine two (or more) variable string manipulations in one step?


Answer: 1

27 hours ago

Is it possible to combine two or more string manipulation functionalities of a variable in BASH (or any other standard Linux command)?

Let's say e.g. I have the variable $XDG_CURRENT_DESKTOP which holds the string ubuntu:GNOME.

Now, I can retrieve the second substring by ${XDG_CURRENT_DESKTOP##*:} → GNOME.

I can also retrieve the lower case string through ${XDG_CURRENT_DESKTOP,,} → ubuntu:gnome.

But how can I combine both functions (→ gnome) in one – simple – command without using a redirection to sed, awk, grep or any other of these – quite heavy weighted – commands and without an additional buffer storage step? e.g.:

local mybuffer="${XDG_CURRENT_DESKTOP##*:}"
echo "${mybuffer,,}"

I want to avoid such a "sub-script" or function call construct to achieve this and I already tried any combination of both mentioned but it seems to be futile.

Is there any other way?

Or do I need to upgrade bash? (using: GNU bash 4.3.11)

Or can any other shell do that?

Added by: Prof. Colin Blick

Answer: 2

30 hours ago

You could do this in bash if you use read to read two variables:

$ IFS=':' read var1 var2 <<<"${[email protected]}"
$ echo "$var2"

The ${[email protected]} construct returns the value of $variable converted to lower case. Then, IFS=':' read sets the input field separator to : for the read command, this way the global IFS is left unchanged after the command exits, and then read var1 var2 will separate its input on : and save the result in the two variables var1 and var2. Note that if you have more than one : on the same line in the input, var1 will have everything up to the first : and var2 everything else. Finally, <<< is a "here string", a simple way to pass a variable as input to a command.

Answer: 3

10 hours ago

Here's a bash5 (not bash4) script:

part2() {
   local -n var=$1
lc() {
   local -n var=$1
part2 fred
lc fred
printf "%s\n" "$fred"



The functions part2 and lc modify the variable whose name is passed to them, without forking. In the end, the original variable (fred) has been modified. You still need the extra variable though.

The alternative, which should work on bash4, is something like this:

part2() { printf "%s" "${1#*:}"; }
lc()    { printf "%s" "${1,,}" ; }
printf "%s\n" "$(lc "$(part2 "$fred")")"

which does not modify any variables (it only manipulates values), but it does create extra forks.

Added by: Nora Blanda

Popular Search

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1 2 3 4 5 6 7 8 9