「awk」は、列名ごとに値を不規則に出力します。

「awk」は、列名ごとに値を不規則に出力します。

helm history(Kubernetesツール)コマンドを使用して、私のビルドの最後のリビジョン番号を取得するbashスクリプトを作成しています。このコマンドの出力は次のとおりです。

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

予想される結果は、3列の数字(最後の値)のみを返すことですREVISION。これで、以下を使用してこれを行うことができます。

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

ただし、「列」はUPDATED不規則で(スペースで区切られた項目)、上記のコマンドはREVISION列が表示されるまで機能しますUPDATED。将来のバージョンでこのhelm historyコマンドが列の順序を変更すると、状況が複雑になる可能性があります。

簡単な例は、STATUS次の列を使用して最後の値を取得しようとする場合です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

REVISION列の順序が変わっても正しい最後の値を取得する方法はありますか?

答え1

検索する列名は、示されている-col=ようにコマンドラインに表示されます。

コードは、その列名を行の先頭またはスペースから検索し、次の列の先頭または行の終わりまでの範囲を記録します。

この情報を使用してeofを待ってから、最後の行から部分文字列を抽出します。

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' 
'

答え2

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

REVISION最初の行では、index() 現在の行の演算を使用して位置を計算します$_。残りのすべての行については /^.../g を一致させてこの位置をスキップします。次に、アンカーポイントを使用して中断した\G部分から一致を開始し、外部から空白以外の文字を取得します\S+

関連情報