3

I'm writing a bash script that uses helm history (Kubernetes tool) command to get the last revision number of my release. The output for the command is like this:

helm history release

    REVISION    UPDATED                     STATUS      CHART                       DESCRIPTION     
    1           Mon Feb 27 12:46:10 2017    SUPERSEDED  chart-solution-0.1.0-beta1  Install complete
    2           Fri Mar  3 11:40:55 2017    SUPERSEDED  chart-solution-0.1.0-beta1  Upgrade complete
    3           Fri Mar  3 11:41:02 2017    DEPLOYED    chart-solution-0.1.0-beta1  Upgrade complete

The expected result is to return only the number 3 (last value) from the REVISION column. I can do that for now using:

helm history release | awk -v col=REVISION 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}} print $c} NR>1{print $c}' | tail -n 1
3

However, the "column" UPDATED is irregular (space separated items), and the above command only works because the REVISION column comes before UPDATED. If in future versions the helm history command change the order of columns, things can get messed.

A simple example is if I a try to get the last value using the column STATUS, which comes after UPDATED:

helm history release | awk -v col=STATUS 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}} print $c} NR>1{print $c}' | tail -n 1
Mar

There is a way to get the correct last REVISION value even if the column order changes?

terdon
  • 234,489
  • 66
  • 447
  • 667
Eduardo Baitello
  • 606
  • 7
  • 19
  • 1
    Since this seems to be fixed width, get the location of REVISION and extract corresponding string from other columns. With gnu awk, the `index` and `substr` functions will be of use – muru Mar 03 '17 at 12:37
  • Are you sure the file isn't actually tab-separated? – terdon Mar 03 '17 at 12:37
  • some tools provides parsable output (like colon separated field) maybe this option exists ? (I didn't know helm). – Archemar Mar 03 '17 at 12:40
  • 1
    @Archemar checking the code, it doesn't look like it: https://github.com/kubernetes/helm/blob/master/cmd/helm/history.go – muru Mar 03 '17 at 13:41

2 Answers2

1

The column name to be searched is provided via the -col= on the command line as shown.

The code searches for the said column name that starts either at the beginning of line or a whitespace and the extent till the beginning of the next column or the end of line is noted.

Armed with this info, we wait till the eof and extract the substring from the last line.

helm history release | perl -slne '$. == 1 and /(?:(?<=^)|(?<=\s))\Q$col\E(?:\s*|$)/ and ($p,$l)=($-[0],$+[0]-$-[0]); eof and print substr($_, $p, $l) =~ s/\s*$//r;' -- -col='REVISION' 
'
0
col='REVISION' \
   perl -lne '
       $. == 1 and /(?:^|\s)(?=$ENV{col}(?:\s|$))/g and $h=pos, next;
       /^.{$h}/g; /\G(\S+)/ and print $1;
       next;
   ' yourfile


col='REVISION' \
   perl -lne '
      $. == 1 and $h = index($_, $ENV{col}), next;
      /^.{$h}/g; /\G(\S+)/ and print $1;
   ' yourfile

On the 1st line we compute the position of the REVISION using the index() operating on the current line $_. For all the remaining lines, we skip past the positions by means of matching /^.../g. Then make use of the \G anchor to start matching from where we left off previously and grab the outwardly lying non-space \S+ characters.