首页 > 解决方案 > 您如何将 txt 中的项目放入 bash 中的可展示表格中?

问题描述

我正在尝试从 Node01.pc 中检索项目并将其放在一个表中。

示例: echo ${NodeCPU[0]}能够从行打印项目。

但是当我使用 printf 或 echo 时,它要么中断,要么不显示数组项的输出。

表格的格式似乎有效,并且仅在不是数组时才显示。难道我可以看到的不仅仅是文件吗?

Node01.pc 包含

192.168.0.99
2
70
16
80
4
4
100
4

VS122:NMAD:20:20:1:1
VS122:NAMD:20:20:1:1
RS123:FEM:10:20:1:1
QV999:BEM:20:20:1:1

但我只需要第 3、5、7、9 行

我不确定最好的方法是什么,或者我什至需要将项目存储到数组中。

我想过从文本文件中检索所有文本并制作一个包含所有数据的新文件,但我不知道该怎么做。

这是我现在拥有的代码。

#!/bin/bash

Node01=($(cat Node01.pc))
Node02=($(cat Node02.pc))
Node03=($(cat Node03.pc))
Node04=($(cat Node04.pc))
Node05=($(cat Node05.pc))

NodeCPU=("${Node01[2]}" "${Node02[2]}" "${Node03[2]}" "${Node04[2]}" "${Node05[2]}")
NodeMEM=("${Node01[4]}" "${Node02[4]}" "${Node03[4]}" "${Node04[4]}" "${Node05[4]}")
NodeHDD=("${Node01[6]}" "${Node02[6]}" "${Node03[6]}" "${Node04[6]}" "${Node05[6]}")
NodeNET=("${Node01[8]}" "${Node02[8]}" "${Node03[8]}" "${Node04[8]}" "${Node05[8]}")

seperator=----------------------
seperator=$seperator$seperator
rows="%-10s| %-7s| %-7s| %-7s| %-7s\n"
TableWidth=140

printf "%-10s| %-7s| %-7s| %-7s| %-7s\n" NodeNumber CPU MEM HDD NET
printf "%.${TableWidth}s\n" "$seperator"

for((i=0;i<=4;i++))
do
    printf "$rows" "$(( $i+1 ))" "${NodeCPU[i]}" "${NodeMEM[i]}" "${NodeHDD[i]}" "${NodeNET[i]}" 
    
done

read

这是我要显示的示例

NodeNumber | CPU | MEM | HDD | NET
----------------------------------
1          | 10  |  20 |  20 | 40
2          | 10  |  20 |  20 | 40
3          | 10  |  20 |  20 | 40
4          | 10  |  20 |  20 | 40
5          | 10  |  20 |  20 | 40

编辑这是我目前得到的:

NodeNumber| CPU    | MEM    | HDD    | NET
--------------------------------------------
     | 4  | 70
     | 5  | 90
     | 6  | 100
     | 6  | 70
     | 40 | 40

我遇到的问题是

printf "$rows" "$(( $i+1 ))" "${NodeCPU[i]}" "${NodeMEM[i]}" "${NodeHDD[i]}" "${NodeNET[i]}"

标签: bashgit-bash

解决方案


为什么要担心所有单独的数组?只需遍历"Node*.pc"当前目录中的所有文件,并将每个文件的内容读入一个数组,readarray然后输出文件计数和元素编号。2, 4, 6, 8以适当的格式排列数组(根据需要调整元素输出),例如

#!/bin/bash

cnt=1   ## file counter

## print heading
printf "NodeNumber | CPU | MEM | HDD | NET\n----------------------------------\n"

for i in Node*.pc; do           ## loop over all Node*.pc files in directory
    readarray -t node < "$i"    ## read contents into array
    ## output count and elements 2, 4, 6, 8 in proper format
    printf "%-11s| %-4s| %-4s| %-4s| %s\n" $((cnt++)) \
    "${node[2]}" "${node[4]}" "${node[6]}" "${node[8]}" 
done

示例使用/输出

将显示的示例数据复制到Node01.pc当前目录中的文件,您将获得:

$ bash node.sh
NodeNumber | CPU | MEM | HDD | NET
----------------------------------
1          | 70  | 80  | 4   | 4

(我调用了脚本node.sh

它将每个文件中的信息输出为单独的行,编号为1, 2, ...“查看内容”,让我知道这是否是您想要的。(您也可以通过将行设置为单个记录中的列并将其视为列来awk更快地做同样的事情)FS=\n

你可以做同样的事情awk

awk '
    BEGIN {
        RS=""; FS="\n"
        printf "NodeNumber | CPU | MEM | HDD | NET\n----------------------------------\n"
    } 
    NF >= 9 {
        printf "%-11s| %-4s| %-4s| %-4s| %s\n",++cnt,$3,$5,$7,$9
    }
' Node*.pc

注意:字段编号从awk1 开始,而在 bash 中,数组索引从 0 开始)

输出是一样的。


推荐阅读