時には数学演算を実行する必要がある場合もあります。bc
またはを使用できることを知っていますecho $(( 6/2 ))
。bc
入力を読み取る関数を直接作成しました。しかし、時には入力に時間がかかります_bc "6/2"
。だから私はこのような質問を持っています:
コマンドラインで数値に対して数学を実行する方法をzsh / bashに教える方法はありますか? 1つの例は1000の言葉と同じくらい価値があります。
$ 6/2
$ 3.0
つまり、zsh / bashは数字を認識して呼び出す必要があることを意味します。紀元前。
答え1
ショートカットAlt- c(bash)
bashでは、readlineユーティリティを使用して単語を先頭calc
に置き、これまでに作成されたテキストを二重引用符で囲むキーシーケンスを定義できます。
bind '"\ec": "\C-acalc \"\e[F\""'
23 + 46 * 89
実行後にたとえば、次のようにするには、次のようにAlt入力cします。
calc "23 + 46 * 89"
Enterキーを押すと、数学演算はcalcで定義された関数によって実行されます。これは簡単かもしれず、はるかに複雑かもしれません。
calc () { <<<"$*" bc -l; }
(+) エイリアス
エイリアスを定義できます。
alias +='calc #'
これにより、これまで入力したコマンドライン全体がコメントアウトされます。次のように入力します。
+ (56 * 23 + 26) / 17
Enter キーを押すと、対応する行が翻訳され、calc #(56 * 23 + 26) / 17
コマンドが呼び出されます。calc
calcがこの関数の場合:
calc(){ s=$(HISTTIMEFORMAT='' history 1); # recover last command line.
s=${s#*[ ]}; # remove initial spaces.
s=${s#*[0-9]}; # remove history line number.
s=${s#*[ ]+}; # remove more spaces.
eval 'bc -l <<<"'"$s"'"'; # calculate the line.
}
calc(){ s=$(history -1 | # last command(s)
sed '$!d;s/^[ \t]*[0-9]*[ \t]*+ //'); # clean it up
# (assume one line commads)
eval 'bc -l <<<"'"$s"'"'; # Do the math.
}
扱いにくい+
zshはエイリアスや文字を受け入れません#
。
値は次のように印刷されます。
$ + (56 * 23 + 26) / 17
77.29411764705882352941
文字列として引用されたaのみが必須であり+
(ワイルドカードなし)、シェル変数を受け入れます。
$ a=23
$ + (56 * 23 + $a) / 17
77.11764705882352941176
(+)機能
いくつかの制限があるので、以下は(bashで)関数を使用してあなたの要求に最も近いものです。
+() { bc -l <<< "$*"; }
次のように動作します。
$ + 25+68+8/24
93.33333333333333333333
問題は、シェルの解析を回避する方法がなく、a *
(たとえば)をpwdのファイルリストに拡張できることです。
空白なしでコマンドラインを作成すると、おそらく大丈夫でしょう。
このような内容は$(...)
拡張されますので、書かないようにご注意ください。
安全な解決策は、評価する文字列を引用することです。
$ + '45 + (58+3 * l(23))/7'
54.62949752111249272462
$ + '4 * a(1) * 2'
6.28318530717958647688
それだけ二つ文字はあなたより短いですが、私_bc "6/2"
にとって+
は、aはより直感的なようです。
答え2
では、zsh
次のことができます。
autoload zcalc
accept-line() {
if [[ $BUFFER =~ '^[ (]*[+-]? *(0[xX]|.)?[[:digit:]]+[^[:alnum:]]' ]]; then
echo
zcalc -e $BUFFER
print -rs -- $BUFFER
BUFFER=
fi
zle .$WIDGET
}
zle -N accept-line
accept-line
ウィジェット(にマップされているEnter)を現在の行が数字(10進数または16進数)で始まることを確認するカスタムウィジェットにオーバーライドします。オプションで、次のコマンド(
に対する偽の肯定を避けるために、数字ではなく文字の検索の後にランダムな数字sが前に付けられます。7zip
または411toppm
。
一致するものがあればそれを渡しzcalc
(シェル変数とすべてのzsh数学関数と数値スタイルを使用できますが、任意の精度をサポートしていないのでbcよりも便利です)、レコードに行を追加して空のコマンドを受け入れます。 。
次のように数字を含む行を入力すると、混乱が発生する可能性があります。
cat << EOF
213 whatever
EOF
または:
var=(
123 456
)
答え3
私はbashのバリエーションを使用しますマジックエイリアスクラック:
asis() { bc <<< "$(history 1 | perl -pe 's/^ *[0-9]+ +[^ ]+ //')"; }
alias c='asis #'
それから:
$ c 1+1
2
$ c -10 + 20 / 5
-6
$ c (-10 + 20) / 5
2
$ c 2^8 / 13
19
$ c scale=5; 2^8 / 13
19.69230
魔法は、エイリアス拡張が発生するということです。今後一般的なコマンドライン処理では、残りの引数とコメント文字を使用してコマンドを生成し、コマンド履歴を使用してコマンドを検索する機能を実装できます。
*
この魔法を使用すると、文字通り、(
その他の文字を入力できます。ただし、これは$
リテラルなので、シェル変数を使用できないことを意味します。
$ x=5.0
$ y=-1.2
$ z=4.7
$ c ($x + $y) > $z
(standard_in) 1: illegal character: $
(standard_in) 1: illegal character: $
(standard_in) 1: illegal character: $
私はいくつかのガイドラインでこの問題を解決しました。
$ echo "x=$x; y=$y; z=$z"
x=5.0; y=-1.2; z=4.7
$ c x=5.0; y=-1.2; z=4.7; (x + y) > z
0
bc
Enter1+1 を入力する方が良いかもしれません。Enter Control+D
bc
ちなみに、私はにデフォルト設定(例えばscale
)を持っていて$HOME/.bc
エイリアスを使いますbc -l
。あなたの使用にはこれらの修正は必要ないかもしれません。
答え4
次のコマンドライン入力は非常に簡単です。
<<< 5+4 bc
<<< 6/3 bc
<<< 7*2 bc
やや複雑な括弧(引用またはエスケープする必要があります)
<<< "(5+4)*2/3" bc
<<< \(5+4\)*2/3 bc