Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Say I run the command SayStuff

$ SayStuff

and the output is

Watermelons and cucumbers

Now. Say I want to extract the substring cucumbers from the output and pipe it into something.
The way I would go about this programmatically would be to split the output into an array by the delimiter Space and reference it by ArrayName[2]. I am fairly new to shell scripts and have only succeeded in digging up semi-cryptic cut examples, none of which made sense.

Any ideas?

share|improve this question
up vote 15 down vote accepted
$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers

The -d ' ' tells cut to split on spaces. -f 3 selects the third column.

You can also use awk, which does the splitting based on space already and makes the columns available as $1, $2, …

$ echo "Watermelons and cucumbers" | awk '{ print $3 }'
cucumbers
share|improve this answer
    
Note that cut will not handle a variable number of spaces, while awk do. – Zitrax Feb 10 at 12:13

I would probably use one of the options already given by @slhck but here are a few more ways of doing this:

  1. Using arrays, as you would in any other language:

    $ foo=( $(SayStuff) ) 
    $ echo ${foo[2]}
    cucumbers
    

    The var=() declares an array, $(command) saves the output of the command. So, foo=( $(SayStuff) ) stores the output of SayStuff into the array foo and yuou then echo it's third element with ${foo[2]}.

  2. sed

    $ SayStuff | sed 's/.* \(.*\)/\1/'
    cucumbers
    

    The sed command will substitute (s///) everything with the last word. The regex matches anything up to a space (.*) which will match everything up to the last space and then captures the last word (\(.*\). Since the word has been captures, we can refer to it as \1.

    A simpler version:

    $ SayStuff | sed 's/.* //'
    cucumbers
    
  3. bash

    $ foo=$(SayStuff); echo ${foo##* } 
    cucumbers
    

    This uses bash's string manipulation abilities, see here for more details.

  4. More bash

    $ SayStuff | while read a b c; do echo $c; done
    cucumbers
    
  5. Perl, where of course, there are many ways to do this:

    $ SayStuff | perl -lane 'print $F[$#F]'
    cucumber
    

    The -a makes perl behave like awk, splitting lines at whitespace and saving into the array @F. We then print the last element of @F ($#F is the number of elements in @F). The -l tells perl to add a newline to each print statement, the -n that it should process STDIN line by line and -e that it should run the script given at the command line.

    $ SayStuff | perl -pe 's/.* //'
    cucumber
    

    The options were explained above, we are just deleting everything till the last space and printing (-p).

    $ perl -le 'print $ARGV[$#ARGV]' $(SayStuff)
    cucumbers
    

    Here we are passing Watermelons and cucumbers as arguments, which perl will save in the @ARG array and so, we print the last element of @ARG.

  6. trickery. This one uses sed to convert spaces to newlines and then tail to print only the last line.

    $ SayStuff | sed 's/ /\n/g' | tail -n 1
    cucumbers
    
  7. grep and regular expressions, using -o which prints only the matched string.

    $ SayStuff | grep -Po '\w+$' 
    cucumbers
    
  8. cheating

    $ SayStuff | grep -o cucumbers
    cucumbers
    
share|improve this answer

Here is some more explanation:

Usage: cut OPTION... [FILE]...

Print selected parts of lines from each FILE to standard output.

   -d, --delimiter=DELIM
          use DELIM instead of TAB for field delimiter

   -f, --fields=LIST
          select only these fields;  also print any line that contains  no
          delimiter character, unless the -s option is specified

So if you need the 3rd field and it is delimited by spaces ' ' then it is

$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3  
cucumbers

If you want the LAST field you probably should use awk.
In this case it becomes:

$ echo "Watermelons and cucumbers" | awk '{ print $NF }'
cucumbers

In awk NF is the number of fields in the line so $NF means the last field in the line.

share|improve this answer
    
basically the same question is here but more generalized: stackoverflow.com/questions/3162385/… Yes you can use other ways but awk is the shortest – zeridon Jan 6 '14 at 15:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .