Bash shell 脚本输出对齐

Bash shell 脚本输出对齐

我的脚本:

date
echo -e "${YELLOW}Network check${NC}\n\n"

while read hostname
do

ping -c 1 "$hostname" > /dev/null 2>&1 &&

echo -e "Network $hostname : ${GREEN}Online${NC}" ||
echo -e "${GRAY}Network $hostname${NC} : ${RED}Offline${NC}"

done < list.txt
        sleep 30
clear
done

正在输出这样的信息:

Network 10.x.xx.xxx : Online   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.x : Online   
Network 139.xxx.x.x : Online   
Network 208.xx.xxx.xxx : Online   
Network 193.xxx.xxx.x : Online

我想清理它以获得这样的东西:

Network 10.x.xx.xxx       : Online  
Network 10.x.xx.xxx       : Offline   
Network 10.x.xx.xxx       : Offline    
Network 10.x.xx.x         : Online    
Network 139.xxx.x.x       : Online  
Network 208.xx.xxx.xxx    : Online    
Network 193.xxx.xxx.x     : Online  
Network 193.xxx.xxx.xxx   : Offline

答案1

用于printf格式化输出(它也是比更便携echo)。我还将存储颜色转义序列的实际值,而不是以需要扩展的形式存储它们echo

RED=$(tput setaf 1) GREEN=$(tput setaf 2) YELLOW=$(tput setaf 3)
NC=$(tput sgr0) 
online="${GREEN}online$NC" offline="${RED}offline$NC"

ping -c 1 "$hostname" > /dev/null 2>&1 && state=$online || state=$offline
printf 'Network %-15s: %s\n' "$hostname" "$state"

%-15s是一种格式规范,它在右侧用空格填充字符串,以便长度(以zsh和中的字符数为单位fish大多数其他 shell/printf 中的字节) 至少为 15。

$ printf '|%-4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcde|
 printf '|%4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcde|

截断:

$ printf '|%.4s|\n' a ab abc abcd abcde
|a|
|ab|
|abc|
|abcd|
|abcd|
$ printf '|%4.4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcd|
$ printf '|%-4.4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcd|

用于格式化列中文本的其他实用程序包括POSIXexpand

printf 'Network %s\t: %s\n' "$hostname" "$state" | expand -t 30

\t(这里每 30 列扩展制表符 ( ) 并使用制表符停止位)

或者BSDcolumn或者POSIXpr

printf 'Network %s\n: %s\n' "$hostname" "$state" | pr -at2

(此处输出 2 个 36 列宽的列(请参阅-w更改页面宽度默认值 72 的选项))。

或者BSDrs

{
   while...
      printf 'Network %s\n: %s\n' "$hostname" "$state"
   done
} | rs -e 0 2

(就像column在读取所有输入之前不会开始输出)。

或者GNUcolumns

printf 'Network %s\n: %s\n' "$hostname" "$state" | columns -w 25 -c 2

zsh还有一些用于字符串填充的参数扩展标志${(l[15])hostname}左边填充${(r[15])hostname}正确的填充(带截断)。添加该标志后m,该填充会考虑字符的显示宽度,而如果没有添加该标志,则假定所有字符都具有相同的显示宽度。

迅速扩张(就像在提示中或在print -P带有标志的参数扩展中启用的那样%),它还支持%F{green}颜色输出,因此您可以执行以下操作:

online='%F{green}online%f'
printf '%s\n' "Network ${(r[15])hostname}: ${(%)online}"

或者:

print -rP "Network ${(r[15])hostname}: $online"

尽管 的内容$hostname也会受到提示扩展的影响,如果promptsubst启用该选项并且 的内容$hostname不受您的控制(如 中hostname='$(reboot)'),这将构成命令注入漏洞

答案2

简单地与column命令:

yourscript.sh | column -t

输出:

Network  10.x.xx.xxx     :  Online
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.x       :  Online
Network  139.xxx.x.x     :  Online
Network  208.xx.xxx.xxx  :  Online
Network  193.xxx.xxx.x   :  Online

答案3

更新您的脚本以将一组数字插入到\t您想要跳出列的位置(制表符)。

输出类似于以下内容的内容将为您提供所需的对齐方式:

Network 10.x.xx.xxx\t: Online   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.x\t: Online   
Network 139.xxx.x.x\t: Online   
Network 208.xx.xxx.xxx\t: Online   
Network 193.xxx.xxx.x\t: Online

答案4

表现甚至比@Roman 更好

yourscript.sh | column -t -s $'\t'

然后添加\t每一行以将其拆分为列。

相关内容