【问题标题】:Format output of array elements with variable lenght可变长度数组元素的格式输出
【发布时间】:2018-05-19 11:17:23
【问题描述】:

我有这个数组,输出到 file.txt: 第一个数组包含子网中的所有 IP (192.168.1.0, 192.168.1.1, ecc) 第二个数组包含一个 1 如果该主机启动,一个 0 如果该主机关闭,以获得这样的矩阵:

192.168.1.0 192.168.1.1 ...
0           1           ...   

如何对齐这些元素?我希望位状态(0 或 1)位于 IP 地址的中心。 考虑到 IP 地址可能会有所不同,具体取决于机器,例如它可以是 71.5.0.0

如果您需要更多信息,我会将所有脚本放在此处:

#!/bin/bash
# written by Cosimo Colaci


# Declarations
ROOT_UID=0
E_NOROOT=65
declare -a iplist

echo "Reading hosts status..."


# Must run as root.
# if [ "$UID" -ne "$ROOT_UID" ]
# then
#  echo "You need to run this script as root. Exiting..."
#  exit $E_NOROOT
# fi



# Find Gateway IP and Netmask
ip_gateway=$(route | tail -1 | awk '{print $1}')
netmask=$(route | tail -1 | awk '{print $3}')
# echo "$netmask"           FOR DEBUG



# Find subnet
OLDIFS="$IFS"
IFS=.
read -r i1 i2 i3 i4 <<< "$ip_gateway"
read -r m1 m2 m3 m4 <<< "$netmask"
subnet_ip=$(printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((ii4 & m4))")
# echo "$subnet_ip"         FOR DEBUG
IFS="$OLDIFS"



# Express netmask in CIDR notation, to know how many hosts to scan
cidr_by_netmask() {
    #function returns prefix for given netmask in arg1
    bits=0
    for octet in $(echo $1| sed 's/\./ /g'); do 
         binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g') 
         let bits+=${#binbits}
    done
    echo "/${bits}"
}

suffix=$(cidr_by_netmask $netmask)
# echo "$suffix"            FOR DEBUG



# First raw of matrix file: all IPs in subnet
iplist=( $(nmap -sL $subnet_ip$suffix | grep "Nmap scan report" | awk '{print $NF}') )

# echo "${iplist[@]}"           FOR DEBUG

let i=1
let j=0
while [ $j -lt ${#iplist[@]} ]
do
  raw1[$i]=${iplist[$j]}
  ((i++))
  ((j++))
done
raw1[0]="#IP/TIME"

for value in ${raw1[@]}
do
  echo -en "$value\t"
done >ip-time_matrix.txt
echo -e "\n" >>ip-time_matrix.txt


# Other raws
let j=1
let k=0

export j
export k

echo "Scanning hosts every 10s..." 
echo "Hit CTRL-C to stop and check file \"ip-time_matrix.txt\""

while true
do
  nmap -sP $subnet_ip$suffix &>temp_esame95a.txt
  raw2[0]="$(date +%T)"
  for ip in ${iplist[@]}
  do
    if grep "$ip" temp_esame95a.txt &>/dev/null
    then
      raw2[$j]="---1---"
    else
      raw2[$j]="---0---"
    fi
    ((j++))
  done
  for value in ${raw2[@]}
  do
    echo -en "$value\t"
  done >>ip-time_matrix.txt
  echo -e "\n" >>ip-time_matrix.txt
  sleep 10
  j=1
done

【问题讨论】:

  • 你能举一个你想要的输出的例子吗?我不认为你想要192.168--1--.1.1e--1--cc 我把位状态(--1--)放在 IP 地址的中心。
  • 当你想要位状态字段在同一列时,每行以bit status开头,避免printf "%15.15s %s" "${ip}" ${bitstatus}
  • 谢谢沃尔特,我不知道我是否能够解释我的问题,但根据你的建议,我解决了我的问题。我需要这个: $ printf "%15s" "$value" 所以,如果 ip 是 1.1.1.1 或 192.192.192.192,它就在列中。谢谢!

标签: arrays bash format output


【解决方案1】:

在评论中建议printf "%15.15s %s" "${ip}" ${bitstatus}。我应该添加一个 \n, printf "%15.15s %s\n" "${ip}" ${bitstatus}。
OP 反应过来,解决了他的问题。

【讨论】:

    【解决方案2】:

    对于数组:

    ips=(192.168.1.0 127.001.0.1 192.168.1.1 192.169.1.1)                    
    raw=(1 1 0 1)                                                            
    

    您可以使用printfcut 命令,

    printf "%15s" "${ips[@]}" | cut -c5-                                               
    printf "%15s" "${raw[@]}" | cut -c5-
    

    对齐输出:

    192.168.1.0    127.001.0.1    192.168.1.1    192.169.1.1             
              1              1              0              1             
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      相关资源
      最近更新 更多