配列パーセンタイルを計算するサンプルシェルコマンドがあります。
$ time zcat input.txt.gz | head -n 999999 | awk 'BEGIN{FS="\t"}{print $13}' | st
--percentile=97.5
75
real 0m3.532s
user 0m8.584s
sys 0m0.648s
2つのパーセンタイルで数字を計算したいので、速度が速いことがわかります。 teeを使用してstdoutをコマンドにリダイレクトします。
mkfifo output_txt;
zcat input.txt.gz | head -n 999999 |
awk 'BEGIN{FS="\t"}{print $13}' |
tee >(st --percentile=2.5) >> output_txt |
st --percentile=97.5 >> output_txt;
cat output_txt; rm output_txt
しかし、それは外に出て立ち往生していません。
fifoを使うべきだと思うので、次のように変更しました。
echo "" > output_txt;
zcat input.txt.gz | head -n 999999 |
awk 'BEGIN{FS="\t"}{print $13}' |
tee >(st --percentile=2.5) >> output_txt |
st --percentile=97.5 >> output_txt;
cat output_txt; rm output_txt
実行されますが、長い数字のリストを出力し、プログラムが各行の分位数を計算するようです。
input.txt
生成できる
for ((i=0; i<999999; i++)); do
number=$(awk 'BEGIN{print int(rand()*1000)/10}')
echo $number >> input.txt
done
=====更新======
@ilkkachuが述べたように、次のコマンドはうまくいきます。
echo "" > output_txt;
zcat input.txt | head -n 999999 |
awk 'BEGIN{FS="\t"}{print $13}' |
tee >(st --percentile=2.5 >> output_txt) |
st --percentile=97.5 >> output_txt;
cat output_txt; rm output_txt
しかし、fifoを使うときは動作しません(まだ付いています)。
アップデート:@Paul_Pedant
FIFOはパイプです。インポートするデータが一部のシステム制限(おそらく4096バイト(POSIX最小)または64KB(通常のLinux)またはその他の制限)に達すると、fifoは他のプロセスが一部のデータを読み取るまで書き込みをブロックします。
これがfifoを使うときに詰まる理由を説明すると思います。