次の形式で時間を出力するプログラムがあります。
2s576039936ns
次の形式に変換する必要があります。
2.576039936
シェルスクリプトでこれをどのように実行できますか?
修正する:このns
セクションは9桁の数字で埋められないので、2s513ns
このような出力が出る可能性があるので2.000000513
。
答え1
2s576039936ns
このソリューションは以下も処理します2s123ns
。
$ echo 2s576039936ns | tr '[:alpha:]' ' ' | awk -- '{ printf "%d.%09d",$1,$2 }'
2.576039936
$ echo 2s123ns | tr '[:alpha:]' ' ' | awk -- '{ printf "%d.%09d",$1,$2 }'
2.000000123
答え2
Bashのこの機能を使用できます(POSIXかどうかわからない)。
x=2s576039936ns
y=${x/s/.}
z=${y/ns/}
echo $z
またはsed
:
echo 2s576039936ns | sed 's/s/./; s/ns//'
どちらの方法も最初に s をドットに変えてから ns を削除します。
まったく異なる場合:
echo 2s576039936ns | awk -F '[ns]' '{print $1 "." $2}'
これはあなたがただ変化を望んでいると仮定します滞在数字ではなく。
答え3
そしてperl
:
$ echo 10000s12576039936ns 1s1ns 0001s1000000ns 12s0ns |
perl -Mbignum -pe 's{(\d+)s(\d+)ns}{$1 + $2 / 1e9}ge'
10012.576039936 1.000000001 1.001 12
算術演算で秒+ナノ秒の値を扱う場合は、任意の精度(ここで使用)が必要です。bignum
たとえば、プロセッサ/Cコンパイラが精度をナノ秒まで維持したい場合、ツールで一般的に使用されるタイプです。算術演算を実行する(シェルなし...)精度が不十分です。perl
struct timespec
clock_gettime()
double
awk
perl
bignum
そしてzsh
:
string='10000s12576039936ns 1s1ns 0001s1000000ns 12s0ns'
set -o extendedglob
newstring=${string//(#b)(<->)s(<->)ns/\
$((match[1] + match[2] / 10**9))${${:-.${(l[9][0])match[2]}}%%(.|)0#}}
10012.576039936 1.000000001 1.001 12
それも提供します$newstring
(ここでは両方の数値に対して整数算術を使用し、このような浮動小数点zsh
についても使用double
します)。
答え4
「テキスト表現」だけを変換したいと思うので、コマンドの出力をパイプできますsed
。次のコマンドは最初に削除され、次にns
置き換えs
られます.
。
~$ echo "2s576039936ns" | sed -e 's/ns//' -e 's/s/./'
2.576039936
修正する
コメントでは、ナノ秒部分は正確に9桁までゼロで埋められないことを指摘しました。この場合、出力が無効になります。この問題を解決するには、次のソリューションを使用できますawk
。
~$ echo "2s576039936ns" | awk -F'n?s' '{printf "%d.%09d\n",$1,$2}'
s
これはフィールド区切り文字としてまたはを使用しns
(マルチキャラクタフィールド区切り文字はマルチ文字列ではなく正規表現として解釈されます)、区切り文字として.
フィールド1とフィールド2を印刷します(後者は0から9まで埋められます) 。小数点の桁)。
したがって、スクリプトで次のものを使用できます。
t=$( your_command | awk -F'n?s' '{printf "%d.%09d\n",$1,$2}' )