Remove characters to right of first space in Bash

8,818

Solution 1

Because there are multiple spaces you want to use

${var%%[[:space:]]*}
# ...^^

to remove the longest trailing substring that starts with a space

With just a single % you're removing the shortest sequence of a space followed by zero or more characters, which is just the last space in the string.

$ echo ">$var<"; echo ">${var%[[:space:]]*}<"; echo ">${var%%[[:space:]]*}<"
>2492  some string continues here  <
>2492  some string continues here <
>2492<

If you're just looking for the first word, you can do this:

read -r word rest_of_string <<<"$var"
echo "I have: $word"

That will take care of leading whitespace, assuming you have not altered the IFS variable.

Solution 2

There is the simple solution of using %% (${var%% *})instead of % (${var% *}). That will remove everything (*) after an initial space.

$ var='2492  some string continues here'
$ echo "${var%% *}"
2492

But that will fail if the string in var has any leading spaces. It is possible to remove the leading spaces with:

$ var=$' \t 2492  some string continues here  '
$ var="${var#"${var%%[![:space:]]*}"}"
$ echo "$var"
2492  some string continues here  
$ echo "${var%%[[:space:]]*}"
2492

That works even if the white-spaces are spaces tabs NL or CR.


Regex

Maybe a more robust solution is to use a regex:

$ var=$' \t 2492  some string continues here  '
$ regex='^[[:space:]]*([^[:space:]]+)'
$ [[ $var =~ $regex ]] && var=${BASH_REMATCH[1]}
$ echo "$var"
2492

Solution 3

You can also use the simple tool cut, who cuts strings based on a delimiter :

echo "$mystring" | cut -d' ' -f 1 

Where :

  • -d' ' sets the delimiter to a space
  • -f 1 gives the first field (based on the delimiter)

Solution 4

You can use native shell string manipulation:

TEST="test  1234 foo"
SPLIT_VAR=${TEST/ */ }

It will replace the first pattern matching " *" (one space then anything) and replace it with " " (one space). So you keep the first word and the first space.

You can see http://www.tldp.org/LDP/abs/html/string-manipulation.html for more usage of string manipulation.

And as a side note, it's also works less evolved shell (tested on busybox's ash implementation).

Share:
8,818

Related videos on Youtube

Joshua Soileau
Author by

Joshua Soileau

Updated on September 18, 2022

Comments

  • Joshua Soileau
    Joshua Soileau almost 2 years
    2492  some string continues here
    

    I would like to convert this to

    2492
    

    in Bash. How would I go about that?

    This feels close, but is not working:

    var="2492  some string continues here  "
    echo ${var%[[:space:]]*}
    
    • Alexander
      Alexander about 6 years
      Will there never be leading whitespace?
    • notw86
      notw86 about 6 years
      If you are asking how to do it in bash you should probably not be using bash to do it. Use Perl or something.
  • Joshua Soileau
    Joshua Soileau about 6 years
    How about if there is a leading space in the string? ` 2492 some string continues here`
  • Angel Todorov
    Angel Todorov about 6 years
    That will remove all the characters.
  • Angel Todorov
    Angel Todorov about 6 years
    [:space:] character class includes space, tab, CR, NL, etc. So it's a catch-all for any whitespace.
  • Digital Trauma
    Digital Trauma about 6 years
    a=($var); echo "${a[0]}" also works for accessing the first word in the case of leading whitespace.
  • Kusalananda
    Kusalananda about 6 years
    I think that's the first time I've seen anyone refer to regular expressions as "more robust" ;-)
  • Kusalananda
    Kusalananda about 6 years
  • Kusalananda
    Kusalananda about 6 years
    Try that with a string that starts with e.g. *.
  • Robert Riedl
    Robert Riedl about 6 years
    @Kusalananda tried it with array=(*2492* *some * *string continues* here)- still works
  • Kusalananda
    Kusalananda about 6 years
    Now add a file in the current directory that contains 2492 in its name, for example myfile-2492.txt, and run again.
  • Robert Riedl
    Robert Riedl about 6 years
    @Kusalananda oh wow, why does this happen ?
  • Kusalananda
    Kusalananda about 6 years
    Filename globbing happens when you create the array of unquoted strings.
  • Robert Riedl
    Robert Riedl about 6 years
    @Kusalananda, I guess I'll have to start with set -f and end with set +f ?
  • Kusalananda
    Kusalananda about 6 years
    That would be one solution to it, yes. You should also quote the ${array[0]}.
  • anonymous at work
    anonymous at work about 6 years
    Quoted my strings, thanks for catching that @Kusalananda
  • MoonCheese62
    MoonCheese62 about 6 years
    Could you please explain the purpose of IFS here? echo "${array[0]}", the only command between the assignment and deletion of IFS, doesn't include anything that would be subject to tokenization with the default setting but not with IFS=" " or the other way around.
  • gronostaj
    gronostaj about 6 years
    I like this one. No regular expressions, no programming languages.