1

Let's assume the following variable:

something="    abc   def      ghi"

I'm trying to use parameter expansion and leave out only the abc. I've tried 10 combinations that made sense and 20 more randomly. The closest I got is the following:

echo ${something% *}
abc def

Is it possible for this to work out? If so, how? Thanks.

1
  • Could this question not be rephrased as "extract first word from bash variable" Commented Sep 13, 2018 at 14:25

5 Answers 5

5

It's going to be tough in a single bash-expansion. You might be interested in this:

$ a="    abc   def      ghi"
$ [[ "${a}" =~ ([^\ ][^\ ]*) ]]
$ echo "${BASH_REMATCH[0]}"

This essentially searches for all words in the string and stores them in the array BASH_REMATCH. More information in man bash section [[ expression ]].

You can also convert things into an array:

$ a="    abc   def      ghi"
$ b=( $a )
$ echo "${b[0]}"

Or you can use read

$ a="    abc   def      ghi"
$ read -r b dummy <<< "${a}"
$ echo "${b}"

But if you really want to use parameter expansion, and you allow the usage of extglob and you do not know the number of words there are in the string, you can do

$ a="    abc   def      ghi"
$ shopt -s extglob
$ a=${a##*([ ])}   #remove the spaces in the front
$ a=${a%% *}       #remove everything from the first space onwards
$ echo "${a}"
Sign up to request clarification or add additional context in comments.

1 Comment

Some great and creative suggestions in the whole thread, I think this is the most extensive answer through.
2

If the string def is know upfront, you can use bash pattern substitution:

echo ${something/ def*/}

That's replacing everything after def by nothing.

You could also use the following if the string def is in the variable a:

a="def"
echo ${something/ ${a}*/}

Comments

2

If it's just the first whitespace-delimited word you want, use read.

read x _ <<< "${something}"

read takes the value of "${something}", and splits it into two words based on the current value of IFS; the first word (abc) is assigned to x, with the second word (consisting of all remains characters) assigned to the throwaway variable _.

2 Comments

Is $_ really throw-away? It's documented as doing a number of things at the bottom of Special Parameters in the man page, and has different uses in different contexts. I'm pretty sure it was throw-away in POSIX shell, but in bash ... perhaps not so much.
It's throwaway in the sense that you don't intend to use the value. Even if you assign to it explicitly, the shell still does its normal assignment to it afterward.
1

You can't do this in a single parameter expansion, instead, do this :

$ x=${something% def*}
$ echo ${x# *}
abc

3 Comments

Ah, I assumed it can't be done in a single parameter expansion. If you mention that in your comment I'll mark it as correct.
Thanks, I can mark it as correct in 3 more mins - will check back in a bit. :P
note that ${x# *} actually removes only one blank at the start of the string and again the shell wordsplitting does the rest. might as well have left that part out.
1

With extglob

shopt -s extglob
echo ${something%%*( )*([^ ])*( )*([^ ])}

The substitution itself does not cut the leading blanks though, the shell word splitting does that. if you quote the argument to echo they will still be there.

The substitution removes the longest possible match for zero or more spaces followed by zero or more characters that are not spaces, followed again by zero or more spaces and zero or more not-spaces at the end of the string.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.