bash + 使用 printf 以特殊格式打印

yae*_*ael 14 bash shell-script printf

我刚刚编写了以下 bash 脚本来检查 Linux 机器列表上的 ping 访问:

for M in $list
 do
   ping -q -c 1  "$M" >/dev/null 
          if [[ $? -eq 0 ]]
   then
    echo "($C) $MACHINE CONNECTION OK"
   else
    echo "($C) $MACHINE CONNECTION FAIL"
   fi

   let C=$C+1
done
Run Code Online (Sandbox Code Playgroud)

这打印:

 (1) linux643 CONNECTION OK
 (2) linux72 CONNECTION OK
 (3) linux862 CONNECTION OK
 (4) linux12 CONNECTION OK
 (5) linux88 CONNECTION OK
 (6) Unix_machinetru64 CONNECTION OK
Run Code Online (Sandbox Code Playgroud)

如何printf在我的 bash 脚本中使用(或任何其他命令)来打印以下格式?

 (1) linux643 ............ CONNECTION OK
 (2) linux72 ............. CONNECTION OK
 (3) linux862 ............ CONNECTION OK
 (4) linux12 ............. CONNECTION OK
 (5) linux88 ............. CONNECTION FAIL
 (6) Unix_machinetru64 ... CONNECTION OK
Run Code Online (Sandbox Code Playgroud)

cho*_*oba 21

使用参数扩展来替换%-s由点产生的空格:

#!/bin/bash
list=(localhost google.com nowhere)
C=1
for M in "${list[@]}"
do
    machine_indented=$(printf '%-20s' "$M")
    machine_indented=${machine_indented// /.}

    if ping -q -c 1  "$M" &>/dev/null ;  then
        printf "(%2d) %s CONNECTION OK\n" "$C" "$machine_indented"
    else
        printf "(%2d) %s CONNECTION FAIL\n" "$C" "$machine_indented"
    fi
    ((C=C+1))
done
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 8

for m in $listzsh语法。在bash它会for i in "${list[@]}"

bash没有填充运算符。您可以使用printf但只能使用空格而不是任意字符进行填充。zsh有填充操作符。

#! /bin/zsh -
list=(
  linux643
  linux72
  linux862
  linux12
  linux88
  Unix_machinetru64
)
c=0
for machine in $list; do
  if ping -q -c 1 $machine >& /dev/null; then
    state=OK
  else
    state=FAIL
  fi
  printf '%4s %s\n' "($((++c)))" "${(r:25::.:):-$machine } CONNECTION $state"
done
Run Code Online (Sandbox Code Playgroud)

填充操作是${(r:25:)parameter}-pad与长度25与空格或${(r:25::string:)parameter}与任何字符串而不是空间-pad。

我们还使用printf '%4s'平垫的(x)使用空间。我们本来可以用的${(l:4:):-"($((++c)))"}。但一个显着的区别是,如果字符串长度超过 4 个字符,${(l)}则会截断它,而它会溢出printf.


Kus*_*nda 6

%s格式说明可以采取精度(%.20s例如),同样,当你想输出一个浮点值到一定的精度(以%.4f为例),输出将是最多从给定的字符串参数的字符。

因此,创建一个包含机器名称和足够多的点以用完点的字符串:

cnt=0
for hname in vboxhost ntp.stupi.se example.com nonexistant; do
   if ping -q -c 1  "$hname" >/dev/null 2>&1; then
       status="OK"
   else
       status="FAIL"
   fi

   printf "(%d) %.20s CONNECTION %s\n" \
       "$(( ++cnt ))" "$hname ...................." "$status"

done
Run Code Online (Sandbox Code Playgroud)

输出:

(1) vboxhost ........... CONNECTION OK
(2) ntp.stupi.se ....... CONNECTION OK
(3) example.com ........ CONNECTION OK
(4) nonexistant ........ CONNECTION FAIL
Run Code Online (Sandbox Code Playgroud)