如何在 {} 中获取以 0 填充的数字(大括号扩展)?

如何在 {} 中获取以 0 填充的数字(大括号扩展)?

我正在尝试编写一个简单的脚本来从主机列表中检索内存和交换使用情况。目前,我能够实现这一目标的唯一方法是编写 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

原因是主机名始终以 3 位数字结尾,并且这些主机从 001-218 开始,因此我需要为for每个组执行不同的循环(001-009、010-099、100-218) 。有没有一种方法可以在一个脚本中完成此操作,而不是将 3 个脚本连接在一起?

答案1

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

所以,你可以这样做:

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

但是,让我们稍微看看命令的内部:

  1. 您使用 grep 然后 awk 调用 free 两次:

    free -m|grep Mem |/bin/awk '{print \$4}';
    free -m|grep Swap|/bin/awk '{print \$4}'
    

    所有这些都可以简化为对freeand 的一次调用awk

    free -m|/bin/awk '/Mem|Swap/{print \$4}'
    
  2. 此外,内部命令可以减少到这个值:

    cmd="echo \$(free -m|/bin/awk '/Mem|Swap/{print \$4}')"
    

然后,整个脚本将如下所示:

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";

答案2

printf '%04d' "$a"$a如果是整数,将输出一个用零填充的四位数字字符串。

例子:

a=14
printf -v b '%04d' "$a"

printf '%s\n' "$b"

将输出

0014

因此,只需像以前一样循环并创建零填充变量并使用它:

for a in {1..9}; do
  printf -v za '%04d' "$a"
  # rest of code, using $za
done

上面的分配za也可以通过以下方式完成

printf -v za '%04d' "$a"   # print to variable za

对 C 程序员来说更具可读性

for (( a = 1; a < 10; ++a )); do
  printf -v za '%04d' "$a"
  # rest of code, using $za
done

我还没有看过其余的代码。

注意: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

答案3

您可以使用seq -w 1 218seq -f "%03g" 1 218来生成您的号码。

答案4

虽然支撑扩张我发现有一个补零方法参数扩展对于改变现有变量更有用:

digits=00000
num=123

# Option 1:
temp=$digits$num
echo ${temp:(-${#digits})}
# prints 00123

# Option 2:
echo ${digits:${#num}:${#digits}}${num}
# prints 00123

相关内容