ASDF GHJKL
ASDF GHJKL

Reputation: 23

Bash parameter substitution and expansion in one go

Is an expression like

a=(asd fgh ijk); b=${a[@]:1:${#a[@]}^};

somehow writable in bash?

I would expect it to capitalize the first letter of each word after the first one.

(I know how to do it in multiple expressions, but I would like to know how to do it by combining the two features (expansion and substitution), if possible...)

Upvotes: 2

Views: 84

Answers (3)

user8017719
user8017719

Reputation:

Not a double substitution, but a short solution:

To take advantage of shift we may use the positional parameters instead of an array.

set -- asd fgh ijk; 
b=$1; shift; printf '%s ' "$b" "${@^}"

Defining a function:

$ cc(){ local b=$1; shift; printf '%s ' "$b" "${@^}"; }
$ cc asd fgh ijk
asd Fgh Ijk

If you need the words as one long string, replace '%s ' with '%s':

$ cc(){ local b=$1; shift; printf '%s' "$b" "${@^}"; }
$ cc asd fgh ijk
asdFghIjk

Upvotes: 1

bishop
bishop

Reputation: 39354

Title case the whole string, then toggle the first character?

declare -c a
a=(asd agh ijk)
b="${a[0]~} ${a[@]:1}"

Upvotes: 1

Benjamin W.
Benjamin W.

Reputation: 52102

There is a way if the first element is the only one to start with that character:

$ a=(asd fgh ijk)
$ echo "${a[@]^[!${a:0:1}]}"
asd Fgh Ijk

This extracts the very first character of the first element, then excludes that character from being uppercased; [!${a:0:1}] expands to [!a], which matches only f and i as the first characters of their elements.

It fails if multiple elements start with the same character, though:

$ a=(asd agh ijk)
$ echo "${a[@]^[!${a:0:1}]}"
asd agh Ijk

Upvotes: 3

Related Questions