次のファイルがあります。
37 * 60 + 55.52
34 * 60 + 51.75
36 * 60 + 2.88
36 * 60 + 14.94
36 * 60 + 18.82
36 * 60 + 8.37
37 * 60 + 48.71
36 * 60 + 34.17
37 * 60 + 42.52
37 * 60 + 51.55
35 * 60 + 34.76
34 * 60 + 18.90
33 * 60 + 49.63
34 * 60 + 37.73
36 * 60 + 4.49
このファイルの各行で方程式を評価し、結果を出力するシェルコマンドまたはBashスクリプトを記述する必要があります。たとえば、1行目では2275.52
印刷されました。各結果は1行に1回印刷されます。
私はもう試した cat math.txt | xargs -n1 expr
、ただしこれは機能しません。 awk
がこれを実行できるようにも思えますが、そのコマンドの構文に慣れていないので、どうなるかわかりません。
これはawk
でうまくいくようです:
while IFS= read i; do
awk "BEGIN { print ($i) }"
done < math.txt
から ここ
($i)
のような算術式の問題を回避するために、$i
ではなく1 > 2
を使用していることに注意してください(print 1 > 2
は1
を2
というファイルに出力し、print (1 > 2)
はその算術式の結果である0
を出力します)。
$i
シェル変数の展開はawk
によってcodeとして解釈されることになるため、これは本質的にコードインジェクションの脆弱性。ファイルに有効な算術式のみが含まれていることを保証できない場合は、いくつかの入力検証を配置する必要があります。たとえば、ファイルにsystem("rm -rf ~")
行がある場合、それは劇的な結果をもたらす可能性があります。
ここが私がそれが最善の方法であるかどうかわからないものです
bc < toto
データで何をしたいかに応じて
francois@zaphod:~$ cat > toto
37 * 60 + 55.52
34 * 60 + 51.75
36 * 60 + 2.88
36 * 60 + 14.94
36 * 60 + 18.82
36 * 60 + 8.37
37 * 60 + 48.71
36 * 60 + 34.17
37 * 60 + 42.52
37 * 60 + 51.55
35 * 60 + 34.76
34 * 60 + 18.90
33 * 60 + 49.63
34 * 60 + 37.73
36 * 60 + 4.49
francois@zaphod:~$ while read ; do echo " $REPLY" | bc ; done < toto
2275.52
2091.75
2162.88
2174.94
2178.82
2168.37
2268.71
2194.17
2262.52
2271.55
2134.76
2058.90
2029.63
2077.73
2164.49
francois@zaphod:~$
bCコマンドがないと、10進値を使用できません。
francois@zaphod:~$ while read ; do echo $(( "REPLY" )) ; done < toto
-bash: 37 * 60 + 55.52: syntax error: invalid arithmetic operator (error token is ".52")
francois@zaphod:~$
Perlを使用している場合:
Perl -ne 'print eval $_,"\n"' math.txt
(私はこれを使用して私のラップトップで毎秒50000行を取得します)。
old-good Pythonの場合:
$ python -c $'import sys;\nfor line in sys.stdin:print(eval(line))' <math.txt
2275.52
2091.75
2162.88
2174.94
2178.82
2168.37
2268.71
2194.17
2262.52
2271.55
2134.76
2058.9
2029.63
2077.73
2164.49
結果だけが必要な場合は、 @ francois-p が提供する答えが得られます
楽しみとゲームのために、paste
とsed
を追加します:
$ paste <(sed 's/\($\)/\1\t=/g' somefile) <(bc < somefile)
37 * 60 + 55.52 = 2275.52
34 * 60 + 51.75 = 2091.75
36 * 60 + 2.88 = 2162.88
36 * 60 + 14.94 = 2174.94
36 * 60 + 18.82 = 2178.82
36 * 60 + 8.37 = 2168.37
37 * 60 + 48.71 = 2268.71
36 * 60 + 34.17 = 2194.17
37 * 60 + 42.52 = 2262.52
37 * 60 + 51.55 = 2271.55
35 * 60 + 34.76 = 2134.76
34 * 60 + 18.90 = 2058.90
33 * 60 + 49.63 = 2029.63
34 * 60 + 37.73 = 2077.73
36 * 60 + 4.49 = 2164.49
Perlの場合:
Perl -ple '$_=eval' ex
Perl -nE 'say eval' ex
pythonの場合:
python3 -qi < ex
python3 -qic 'import sys; sys.ps1=""' < ex
Haskellの場合:
ghci < ex
ghci < ex | grep -Po '> \S+$'
計算あり:
calc -f ex # apt install apcalc if necessary
bash/kshに直接(Edit:結局のところ、bash
はこれを行うことができません。 ksh
のみ-これを指摘してくれてありがとう):
_$ while read l
> do
> echo $(($l))
> done <<!
> 37 * 60 + 55.52
> 34 * 60 + 51.75
> 36 * 60 + 2.88
> 36 * 60 + 14.94
> 36 * 60 + 18.82
> 36 * 60 + 8.37
> 37 * 60 + 48.71
> 36 * 60 + 34.17
> 37 * 60 + 42.52
> 37 * 60 + 51.55
> 35 * 60 + 34.76
> 34 * 60 + 18.90
> 33 * 60 + 49.63
> 34 * 60 + 37.73
> 36 * 60 + 4.49
> !
2275.52
2091.75
2162.88
2174.94
2178.82
2168.37
2268.71
2194.17
2262.52
2271.55
2134.76
2058.9
2029.63
2077.73
2164.49
_
これには、ごく最近のバージョンのシェルが必要になる場合があります-$((...))
は、整数演算のみを行うために使用されます。
awk
/python
の使用:
python -c "$(awk '{printf "print %s;", $0}' math.txt)"
ここではawk
を使用して、ファイルをpythonが受け入れる入力にフォーマットし、その後pythonが処理を実行しています。
あるいは、Perl
はほとんど同じ方法で使用できます。
Perl -le "$(awk '{printf "print %s;", $0}' math.txt)"
awk
を直接使用:
awk '{ printf "%f\n", $0 }' math.txt
$0
は、ファイルから1行ずつ読み取られる行全体を表します。
さらに、厄介な注射の影響を受けません。行を浮動小数点数としてのみ評価します。
混乱をbc -l
にフィードするだけで、式の行ごとに1行の結果が返されます。 (-l
は数学ライブラリをロードします。また、scale
をより高い値に設定するため、小数の結果が得られます。)