Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

3 Answers 3

up vote 11 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

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 at 15:48
    
And comment removed and replaced with +1 :). –  terdon Jan 6 at 16:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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