Stdinからデータの列を読み取り、それらを処理(スムージング効果を適用)してからstdoutに出力するブラックボックスUNIXプログラムをBashシェルで使用しています。私は、UNIXパイプで使用します。
generate | smooth | plot
より平滑化するために、平滑化を繰り返すことができるため、Bashコマンドラインから次のように呼び出すことができます。
generate | smooth | smooth | plot
あるいは
generate | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | plot
これは不穏になっています。 Bashラッパーをsmooth
にパイプして、その出力をsmooth
の新しいインスタンスに任意の回数だけフィードバックできるようにしたいと思います。
generate | newsmooth 5 | plot
の代わりに
generate | smooth | smooth | smooth | smooth | smooth | plot
最初の試みは、現在のディレクトリに一時ファイルを生成して削除するBashスクリプトでしたが、書き込みアクセス権のあるディレクトリにいない場合は醜くなり、中断されたときにガベージファイルも残されました。
smooth
プログラムには引数はありません。
そのようなプログラムを「ラップ」して呼び出しの数をパラメーター化するよりエレガントな方法はありますか?
あなたはそれを再帰的な関数でラップすることができます:
smooth() {
if [[ $1 -gt 1 ]]; then # add another call to function
command smooth | smooth $(($1 - 1))
else
command smooth # no further
fi
}
これを次のように使用します
generate | smooth 5 | plot
これは
generate | smooth | smooth | smooth | smooth | smooth | plot
必要なsmooth
コマンドの数と同じ数のコンマを入力できる場合は、シェルのコンマ区切りの大括弧拡張を利用できます。
TL; DR
サンプルケースのコマンドライン全体は次のようになります。
generate | eval 'smooth |'{,,,,} plot
注意:
smooth |
の繰り返しを増やしたり減らしたりする場合は、カンマを追加または削除しますplot
の前に|
はありません。これは、ブレース拡張によって生成された最後のsmooth |
文字列に含まれているためです。smooth
に引数を指定することもできますが、開き括弧の前にある引用符で囲まれた固定部分に引数を正しく含めることができます。いずれの場合も、コマンドのall繰り返しにそれらを提供することを覚えておいてください仕組み
カンマで区切られたブレース展開を使用すると、指定された固定部分と指定された可変部分で構成される文字列を動的に生成できます。 a{b,c,d}
がab ac ad
を生成するように、指定された変数部分と同じ数の文字列を生成します。
ここでの小さなトリックは、empty変数部分のリストを作成する場合、つまり中括弧内にコンマのみを使用する場合、ブレース拡張は単にコピーを生成するということです固定部分のみ。例えば:
smooth{,,,,}
生成されます:
smooth smooth smooth smooth smooth
4コンマは5つのsmooth
文字列を生成することに注意してください。これが、このブレース拡張のしくみです。コンマに1を加えた数の文字列を生成します。
もちろん、あなたのケースでは各smooth
を区切る|
も必要なので、固定部分に追加するだけですが、適切に引用してシェルnotはそれをすぐに解釈します。あれは:
'smooth|'{,,,,}
生成されます:
'smooth|' 'smooth|' 'smooth|' 'smooth|' 'smooth|'
常に、固定部品をすぐに開きブレースに隣接して配置するように注意してください。つまり、'
と{
の間にスペースを入れないでください。 。
(固定部分でシェル変数を展開する必要がある場合は、固定部分を形成するために、単一引用符の代わりに二重引用符を使用することもできます。余分なエスケープに注意してくださいシェルの特殊文字が二重引用符で囲まれた文字列の中にある場合に必要です。
この時点で、シェルに最終的にパイプラインコマンドとして解釈させるために、その文字列にeval
を適用する必要があります。
したがって、すべてをまとめると、サンプルケースのコマンドライン全体は次のようになります。
generate | eval 'smooth |'{,,,,} plot