我的目标是使用(仅使用case+ esac)验证数字范围,并打印该范围。例如:
>=0<=80>=81<=100我下面的脚本的问题>=0<=90仅当数字介于 0 和 9 之间时才打印。如何修复我的脚本,使其根据数字范围打印正确的输出?
#!/bin/ksh
read number
case $number in
[0-80]) echo ">=0<=80";;
[81-100]) echo ">=81<=100";;
[101-120]) echo ">=101<=120";;
[121-300]) echo ">=121<=300";;
esac
Run Code Online (Sandbox Code Playgroud) bash外壳的算术评估能力设置了限制。该手册简明扼要地介绍了 shell 算术的这一方面,但指出:
评估是在固定宽度的整数中完成的,不检查溢出,但除以 0 会被捕获并标记为错误。运算符及其优先级、结合性和值与 C 语言中的相同。
这指的是哪个固定宽度整数实际上是关于使用哪种数据类型(以及为什么会这样的细节超出此范围),但极限值/usr/include/limits.h以这种方式表示:
# if __WORDSIZE == 64
# define ULONG_MAX 18446744073709551615UL
# ifdef __USE_ISOC99
# define LLONG_MAX 9223372036854775807LL
# define ULLONG_MAX 18446744073709551615ULL
Run Code Online (Sandbox Code Playgroud)
一旦你知道了这一点,你就可以像这样确认这个事实状态:
# getconf -a | grep 'long'
LONG_BIT 64
ULONG_MAX 18446744073709551615
Run Code Online (Sandbox Code Playgroud)
这是一个64 位整数,它在算术评估的上下文中直接在 shell 中转换:
# echo $(((2**63)-1)); echo $((2**63)); echo $(((2**63)+1)); echo $((2**64))
9223372036854775807 //the practical usable limit for your everyday use
-9223372036854775808 //you're that much "away" from 2^64
-9223372036854775807
0 …Run Code Online (Sandbox Code Playgroud) 今天早上我的搜索是关于如何在 bash 中比较两个十进制数,我找到了这个答案:如何与 shell 脚本中的浮点数进行比较。然而,这个答案不包括这里的答案:
$ [[ ((3.56 < 2.90)) ]]; echo $?
1
$ [[ ((3.56 < 4.90)) ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)
考虑到该答案已被否决,并且看起来有些不寻常的 bashism,这种算术评估的准确性是否值得信赖?
假设我有一堆表示内存量的数字,例如以“86k或”320m或“或”的形式书写1.7g。如何在命令行中计算它们的总和,并获得人类可读的结果?
能够计算减法也很好。完美的工具将处理多组符号(例如1g/ 1G/ 1GB/ 1Go/ 1GiB/ 1.7Gio)及其含义(二进制或十进制乘数)。
我正在寻找一个纯粹的计算器。这些数字不一定是我磁盘上某些文件的大小,因此诸如find、stat或 之du类的工具不是一种选择。
这显然很容易实现(在精度方面有一些障碍),但如果这还不存在,我会被诅咒!
如何将 8 个字节“读取/解释”为无符号整数(Little Endian)?
也许为此有一个 Bash-fu 魔法转换?
更新:
在我的问题的解释中,似乎有些事情发生了交叉。这是我正在尝试做的一个更广泛的例子。
我想读取文件的第一个(也是最后一个)64k。每个 8 字节字将被解释为 64 位小端无符号整数。这些整数将用于唯一标识文件的散列计算。所以有很多计算要进行, ? 速度是首选,但不是关键。(我为什么要这样做?因为smplayer散列其播放的媒体 .ini 文件的名称,我想访问和修改这些文件,所以我在 Bash 中模仿了 smplayer 的 C++ 代码。)
迎合接受管道输入的解决方案将是最佳的,并且可能是必不可少的,因为 Bash 变量无法处理 \x00..
我意识到像这样的东西可能更适合 Python、Perl 和 C/C++ 之类的东西,但我不知道 Python 和 Perl,虽然我可以用 C++ 来做,但我已经好几年没用了它,我正试图专注于 Bash。
简短的 Perl 和 Python 片段很好。Bash 是首选(但不以牺牲速度为代价)。
是否可以在以下内容中执行以下操作emacs:
查询用数字 +n 替换区域中的所有数字,例如,如果您有:
12 and 7 are nice numbers
Run Code Online (Sandbox Code Playgroud)
让 n 为 3,那么它应该转换为
15 and 10 are nice numbers
Run Code Online (Sandbox Code Playgroud) 如何以“[AZ][0-9]*”或例如:“A000001”的形式迭代字符串?
收到变量后我拆分:
current_=$(mysql -h"$mysqlhost" -u"$mysqluser" -p"$PASS" "$DBNAME" -se "SELECT current_ FROM $GLOBALDB;")
current_number=$(echo $current_ | grep -oh "[0-9]*")
current_letter=$(echo $current_ | grep -oh "[A-Z]*")
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试添加 1 时:
# add 1 & keep all leading zeros "000001"
next_number=$(printf %06d $(($current_number + 1)))
Run Code Online (Sandbox Code Playgroud)
它计数到“000009”并回滚到“000000”。
我加入如下:
next_=$(echo "$current_letter$next_number")
Run Code Online (Sandbox Code Playgroud)
关于字母迭代,我正在考虑使用关联数组?或大括号扩展{A..Z},但这是一个完全不同的问题。
假设两个数字存储在两个不同的文件中,a.txt并且b.txt.
每个数字都足够大(超过 30 位),不支持bash.
我如何将它们添加到 shell 中?
我编写了一个脚本来 ssh 远程主机,执行命令,将输出保存到文件,并检查输出。但是(( success++ ))当迭代 array 中的第一项时,它总是在 line 处静默退出workers。如果我替换(( success++ ))为echo "process $worker",它将正常工作并打印所有主机。我无法弄清楚出了什么问题。
#!/bin/bash
set -x
set -e
workers=('host-1' 'host-2' 'host-3')
output_dir=$(mktemp -d)
for worker in ${workers[@]}; do
ssh $worker '
echo abc
echo OK
' > "$output_dir/$worker" &
done
echo "waiting..."
sleep 3
wait
success=0
regexp='OK$'
for worker in ${workers[@]}; do
output=`cat "$output_dir/$worker"`
if [[ "$output" =~ $regexp ]]; then
(( success++ ))
fi
done
echo "Total ${#workers[@]}; success: $success; failure: …Run Code Online (Sandbox Code Playgroud) 是否可以使用 bash 减去包含 24 小时时间的变量?
#!/bin/bash
var1="23:30" # 11:30pm
var2="20:00" # 08:00pm
echo "$(expr $var1 - $var2)"
Run Code Online (Sandbox Code Playgroud)
运行它会产生以下错误。
./test
expr: non-integer argument
Run Code Online (Sandbox Code Playgroud)
我需要输出以十进制形式出现,例如:
./test
3.5
Run Code Online (Sandbox Code Playgroud) arithmetic ×10
bash ×7
shell ×6
date ×1
emacs ×1
ksh ×1
replace ×1
shell-script ×1
variable ×1