Mat*_*ott 12 scripting bash for
我正在尝试编写一个简单的脚本来从主机列表中检索内存和交换使用情况。目前,我能够实现这一目标的唯一方法是编写 3 个单独的脚本:
for a in {1..9}; do echo "bvrprdsve00$a; $(ssh -q bvrprdsve00$a "echo \$(free -m|grep Mem|/bin/awk '{print \$4}';free -m|grep Swap|/bin/awk '{print \$4}')")"; done > /tmp/svemem.txt;
for a in {10..99}; do echo "bvrprdsve0$a; $(ssh -q bvrprdsve0$a "echo \$(free -m|grep Mem|/bin/awk '{print \$4}';free -m|grep Swap|/bin/awk '{print \$4}')")"; done >> /tmp/svemem.txt;
for a in {100..218}; do echo "bvrprdsve$a; $(ssh -q bvrprdsve$a "echo \$(free -m|grep Mem|/bin/awk '{print \$4}';free -m|grep Swap|/bin/awk '{print \$4}')")"; done >> /tmp/svemem.txt
Run Code Online (Sandbox Code Playgroud)
这样做的原因是主机名总是以 3 位数字结尾,而这些主机从 001-218 开始,所以我需要为每组 (001-009、010-099、100-218) 执行不同的 for 循环. 有没有一种方法可以在一个脚本中执行此操作而不是将 3 个连接在一起?
ImH*_*ere 16
Bash 括号扩展可以生成带前导零的数字(因为 bash 4.0 alpha+ ~2009-02-20):
$ echo {001..023}
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023
Run Code Online (Sandbox Code Playgroud)
所以,你可以这样做:
for a in {001..218}; do echo "bvrprdsve$a; $(ssh -q bvrprdsve$a "echo \$(free -m|grep Mem|/bin/awk '{print \$4}';free -m|grep Swap|/bin/awk '{print \$4}')")"; done >> /tmp/svemem.txt
Run Code Online (Sandbox Code Playgroud)
但是,让我们稍微看看命令内部:
您拨打了两次免费电话,分别使用 grep 和 awk:
free -m|grep Mem |/bin/awk '{print \$4}';
free -m|grep Swap|/bin/awk '{print \$4}'
Run Code Online (Sandbox Code Playgroud)
一切都可以简化为对free
and 的一次调用awk
:
free -m|/bin/awk '/Mem|Swap/{print \$4}'
Run Code Online (Sandbox Code Playgroud)此外,内部命令可以减少到这个值:
cmd="echo \$(free -m|/bin/awk '/Mem|Swap/{print \$4}')"
Run Code Online (Sandbox Code Playgroud)然后,整个脚本将如下所示:
b=bvrprdsve;
f=/tmp/svemem.txt;
cmd="echo \$(free -m|/bin/awk '/Mem|Swap/{print \$4}')";
for a in {001..218}; do echo "$b$a; $(ssh -q "$b$a" "$cmd")"; done >> "$f";
Run Code Online (Sandbox Code Playgroud)
printf '%04d' "$a"
如果$a
是整数,将输出一个填充零的四位字符串。
例子:
a=14
printf -v b '%04d' "$a"
printf '%s\n' "$b"
Run Code Online (Sandbox Code Playgroud)
会输出
0014
Run Code Online (Sandbox Code Playgroud)
所以就像以前一样循环并创建您的零填充变量并使用它:
for a in {1..9}; do
printf -v za '%04d' "$a"
# rest of code, using $za
done
Run Code Online (Sandbox Code Playgroud)
za
上面的赋值也可以用
printf -v za '%04d' "$a" # print to variable za
Run Code Online (Sandbox Code Playgroud)
使 C 程序员更具可读性
for (( a = 1; a < 10; ++a )); do
printf -v za '%04d' "$a"
# rest of code, using $za
done
Run Code Online (Sandbox Code Playgroud)
我还没有看其余的代码。
注意:ksh
可以在变量上设置一个属性,使其扩展始终为零填充:
typeset -Z4 za
for (( a = 1; a < 10; ++a )); do
za="$a"
printf "%s\n" "$za"
done
0001
0002
0003
0004
0005
0006
0007
0008
0009
Run Code Online (Sandbox Code Playgroud)
尽管大括号扩展具有零填充方法,但我发现参数扩展对于更改现有变量更有用:
digits=00000
num=123
# Option 1:
temp=$digits$num
echo ${temp:(-${#digits})}
# prints 00123
# Option 2:
echo ${digits:${#num}:${#digits}}${num}
# prints 00123
Run Code Online (Sandbox Code Playgroud)