44

I am having a variable which shows on echo like this

$ echo $var
129 148

I have to take only 129 as output. How will I split 129 and 148?

2
71

In addition to jasonwryan's suggestion, you can use cut:

echo $var | cut -d' ' -f1

The above cuts the echo output with a space delimiter (-d ' ') and outputs the first field (-f1)

3
  • it is not working. i already used it. it says command not found.
    – surbhi
    Mar 19 '15 at 6:56
  • 4
    @surbhi What says command not found? cut is a standard utility. Your script probably has an error somewhere else. More generally, never say “it is not working”. Always say exactly what code you ran, exactly what happened, and copy-paste error messages. Mar 19 '15 at 22:48
  • This answer should be accepted, as it's the most concise and direct way. It won't work in cases that are more complicated than the given example, of course.
    – dancow
    Jan 5 '17 at 14:56
23

A neat way to do this is to use a bash array to split up a string on spaces. You can declare an array simply by using brackets:

var="129 148     181"
vars=( $var )
echo "First  word of var: '${vars[0]}'"
echo "Second word of var: '${vars[1]}'"
echo "Third  word of var: '${vars[2]}'"
echo "Number of words in var: '${#vars[@]}'"
4
  • this says command not found
    – surbhi
    Mar 19 '15 at 6:58
  • It depends on you using bash. If you are using a different shell it may not work. echo $SHELL should show: /bin/bash or similar.
    – gogoud
    Mar 19 '15 at 7:01
  • doesn't work in zsh ;(
    – TonyH
    Aug 22 '19 at 14:12
  • This does work in ZSH zoom="one two three"; declare -a zoomie=( $( echo $zoom | cut -d' ' -f1- ) ); echo ${zoomie[2]};
    – TonyH
    Aug 22 '19 at 14:17
2

TL;DR

${var%% *}

$ echo "$var"
129 148
$ echo "${var%% *}"
129

Commentary

echo "${var% *}" && echo "${var#* }"... – jasonwryan

While there are a bazillion ways to answer your question, the simplest is Parameter Expansion, which is what Jason suggested in the comments. I believe it is right tool for this exact question.

The other answers here (piping to cut and splitting into an array) are not wrong, by the way. They are versatile solutions that make it easier when your next question is, “So, how do I get the 2nd or nth number?” Simple problems rarely stay simple for long.

Downsides

This method might not work everywhere, though I'm hard pressed to find a place it doesn't. It of course works in bash, the default interactive shell on most Unix boxes, and zsh, which is the default in MacOS. Even limited shells you'll find on routers, such as ash and dash, which I expected to break, work fine with Parameter Expansion.

Sidenote about ${var%% *} versus ${var% *}

You may have noticed that I used two percent signs instead of one as Jason had suggested. The difference is %% deletes the longest matching string and % the shortest. For example, if var contained three numbers, you'd see this:

$ echo "$var"
129 148 167
$ echo "${var%% *}"
129
$ echo "${var% *}"
129 148

For Further Reading

If you've made it this far, you're probably wondering, “Where can I learn more about this magic called Parameter Expansion?” The answer is, in the documentation for your shell, e.g., man bash. Here is an extract from the section on Parameter Expansion from the bash manpage:

Remove matching prefix pattern.

${parameter#word}

${parameter##word}

The word is expanded to produce a pattern just as in pathname expansion, and matched against the expanded value of parameter using the rules described under Pattern Matching. If the pattern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ‘#’ case) or the longest matching pattern (the ‘##’ case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

Remove matching suffix pattern.

${parameter%word}

${parameter%%word}

The word is expanded to produce a pattern just as in pathname expansion, and matched against the expanded value of parameter using the rules described under Pattern Matching. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ‘%’ case) or the longest matching pattern (the ‘%%’ case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

6
  • bash is not the default shell on most Unices. It is the sh of macOS, cygwin and a minority of Linux-based OSes. It is the GNU shell. It's the default user login shell on many Unices these days. zsh used to be sh on macOS (called MacOS/X at the time) in very old versions. Now sh is bash there. The default user shell changed from bash to zsh in recent versions though. In any case those parameter expansion operators are from ksh and are standard so should be available in most modern sh implementations Aug 1 at 21:35
  • Thanks, Stéphane. Yes, Korn shell (ksh) should be given credit for inventing parameter expansion as well as many other great features that people now take for granted in bash.
    – hackerb9
    Aug 1 at 21:51
  • 1
    Technically, parameter expansion (like $1, $2...) was in the original Unix shell (now usually referred as the Thompson shell) from the early 70s, the Bourne shell (late 70s) added variables (a new type of parameter) and a few parameter expansion operators such as ${var-default}. And ksh added a few more including those ones (from the 80s). zsh added hundreds more (from the 90s), bash a few of its own like ${var,,} and many it copied from ksh88, ksh93, mksh in addition to the Bourne ones. Aug 1 at 21:56
  • Thank you, again, Stéphane. You are a wealth of knowledge about shell arcana! I'm guessing you learned this history by actually being there when these changes happened. Have you written a book detailing the /bin/sh family tree yet? If not, please do. I'd buy it.
    – hackerb9
    Aug 2 at 0:03
  • By the way, I notice that you edited my answer and added double-quotes that I had intentionally left out. I feel like it would be wrong to add syntax that was not in the question and fail to add a corresponding section explaining exactly why, including examples of the difference. (As I did for the %% versus %). Since the difference is not germane to this specific question, I'd prefer if the double-quotes were removed. Would you be willing to revert your change, please? Thanks!
    – hackerb9
    Aug 2 at 0:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.