14

シェルスクリプトで1.503923などの浮動小数点数を使用して算術演算を行う方法は?浮動小数点数は、ファイルから文字列として取得されます。ファイルの形式は次のとおりです。

1.5493482,3.49384,33.284732,23.043852,2.2384...
3.384,3.282342,23.043852,2.23284,8.39283...
.
.
.

これが私が動作するために必要ないくつかの単純化されたサンプルコードです。算術演算まではすべて正常に機能します。ファイルから行をプルしてから、その行から複数​​の値をプルします。これらのファイルは巨大なので、検索処理時間を短縮できると思います。

# set vars, loops etc.

while [ $line_no -gt 0 ]
do
    line_string=`sed -n $line_no'p' $file_path`  # Pull Line (str) from a file
    string1=${line_string:9:6}                   # Pull value from the Line
    string2=${line_string:16:6}
    string3=...
    .
    .
    .
    calc1= `expr $string2 - $string7` |bc -l     # I tried these and various
    calc2= ` "$string3" * "$string2" ` |bc -l    # other combinations
    calc3= `expr $string2 - $string1`
    calc4= "$string2 + $string8" |bc
    .
    .
    .
    generic_function_call                        # Use the variables in functions
    line_no=`expr $line_no - 1`                  # Counter--
done

私が得続ける出力:

expr: non-numeric argument
command not found
4

4 に答える 4

14

私はあなたが使うべきだと信じています:bc

例えば:

echo "scale = 10; 123.456789/345.345345" | bc

(これはUNIXの方法です。各ツールは本来の機能をうまく実行することに特化しており、すべてが連携して優れた機能を実行します。優れたツールを他のツールとエミュレートしないで、連携させてください。)

出力:

.3574879198

1またはの代わりにのスケールで10

echo "scale = 1; 123.456789/345.345345" | bc

出力:

.3

これは丸めを実行しないことに注意してください。

より複雑な操作を行う必要がある場合はawkに、最も複雑な操作を行う場合はperlに切り替えることを強くお勧めします。

例:awkで実行された操作:

# create the test file:
printf '1.5493482,3.49384,33.284732,23.043852,2.2384,12.1,13.4,...\n' > somefile
printf '3.384,3.282342,23.043852,2.23284,8.39283,14.1,15.2,...\n'    >> somefile

# do OP's calculations (and DEBUG print them out!)

awk -F',' '
   # put no single quote in here... even in comments! you can instead print a: \047 
   # the -F tell awk to use "," as a separator. Thus awk will automatically split lines for us using it. 
   # $1=before first ","  $2=between 1st and 2nd ","  ... etc.
    function some_awk_function_here_if_you_want() {  # optionnal function definition
         # some actions here. you can even have arguments to the function, etc.
         print "DEBUG: no action defined in some_awk_function_here_if_you_want yet ..."
    }
    
    BEGIN      {  rem="Optionnal START section. here you can put initialisations, that happens before the FIRST file-s FIRST line is read"
    }
    
    (NF>=8)    {  rem="for each line with at least 8 values separated by commas (and only for lines meeting that condition)"
                  calc1=($2 - $7)
                  calc2=($3 * $2)
                  calc3=($2 - $1)
                  calc4=($2 + $8)
                  # uncomment to call this function :(ex1): #  some_awk_function_here_if_you_want
                  # uncomment to call this script:(ex2): # cmd="/path/to/some/script.sh \"" calc1 "\" \"" calc2 "\" ..." ; rem="continued next line"
                  # uncomment to call this script:(ex2): # system(cmd); close(cmd) 
                  line_no=(FNR-1) # ? why -1? .  FNR=line number in the CURRENT file.   NR=line number since the beginning (NR>FNR after the first file ...)
                  print "DEBUG: calc1=" calc1 " , calc2=" calc2 " , calc3=" calc3 " , calc4=" calc4 " , line_no=" line_no
                  print "DEBUG fancier_exemples: see man printf for lots of info on formatting (%...f for floats, %...d for integer, %...s for strings, etc)"
                  printf("DEBUG: calc1=%d , calc2=%10.2f , calc3=%s , calc4=%d , line_no=%d\n",calc1, calc2, calc3, calc4, line_no)
    }

    END        {  rem="Optionnal END section. here you can put things that need to happen AFTER the LAST file-s LAST line is read"
    }
      
'  somefile # end of the awk script, and the list of file(s) to be read by it.
于 2013-01-08T19:13:49.467 に答える
10

これはどうですか?

calc=$(echo "$String2 + $String8"|bc)

これbcにより、$String2と$String8の値が追加され、結果が変数に保存されますcalc

于 2013-01-08T19:14:14.880 に答える
9

「bc」がない場合は、「awk」を使用できます。

calc=$(echo 2.3 4.6 | awk '{ printf "%f", $1 + $2 }')
于 2014-03-03T09:36:49.010 に答える
2

bcのスケールは精度であるため、スケールが4の場合、bc <<<'scale = 4; 22.0 / 7'と入力すると、答えとして3.1428が得られます。8のスケールを使用すると、浮動小数点の後の8つの数値である3.14285714が得られます。したがって、スケールは精度係数です

于 2013-09-09T22:26:48.683 に答える