bash - 如何将终端输出块拆分为可以循环的数组元素
问题描述
只是寻找将多行输出拆分的最佳实践方法,例如您可能从命令或 curl 请求中获得使用 Bash 或 Zsh 的条目数组
例如,如果一个命令或打印一个文件给出了一个输出
"User A:
Name: Bob
Age: 36
User B:
Name: Jeff
Age: 42"
你将如何创建一个数组,其中每个用户都是数组中的一个条目?
或者,如果您的输出设备类似于
"Computer A:
Name Bob's Computer
Serial 123456
Uptime 12hr
Computer B:
Name Jeff's Computer
Serial 789101
Uptime 8hr"
您将如何将其拆分为一组计算机,以便您可以执行诸如通过数组中的元素数量查看有多少台计算机,或者将它们逐个传递给另一个命令等事情?
我一直在寻找分割字符串和输出的方法,我找到的所有答案似乎都是针对用单个字符分隔符分割单行。我认为这样做的方法是在上述示例中使用“用户”或“计算机”作为分隔符进行拆分,或者将它们用作读取和读取的模式,但我不知道该怎么做在 Bash 中?
提前致谢
解决方案
假设:
- 您想将这些行拆分为例如“计算机 A”块和“计算机 B”块,然后将计算机(或用户)名称存储到一个数组中。
- (可能是可选的)您想要解析诸如“名称”、“序列”之类的属性行......并将它们存储在数组数组中。
那么请您尝试以下方法:
#!/bin/bash
str="Computer A:
Name Bob's Computer
Serial 123456
Uptime 12hr
Computer B:
Name Jeff's Computer
Serial 789101
Uptime 8hr"
keyword="Computer" # the keyword to split the lines into array
declare -A hash # create associative array
i=0 # index of the "real" array name
readarray -t a <<< "$str" # read the string splitting on newlines
for line in "${a[@]}"; do # loop over lines
if [[ $line =~ ^${keyword}[[:blank:]]+([^:]+): ]]; then
# if the line starts with the "keyword"
name="${BASH_REMATCH[1]}" # name is assigned to "A" or "B" ...
hash[$name]="array$i" # define "real" array name and assign the hash value to it
declare -A "array$i" # create a new associative array with the name above
declare -n ref="array$i" # "ref" is a reference to the newly created associative array
(( i++ )) # increment the index for new entry
else
read -r key val <<< "$line" # split on the 1st blank character
key=${key%:} # remove traiking ":"
key=${key## } # remove leading whitespace(s)
ref[$key]=$val # store the "key" and "val" pair
fi
done
print number of elements of the array
echo "The array has ${#hash[@]} elements"
# print the values of each array of the array
for i in "${!hash[@]}"; do # loop over "A" and "B"
echo "$i" # print it
declare -n ref=${hash[$i]} # assign ref to array name "array0" or "array1" ... then make it an indirect reference
for j in "${!ref[@]}"; do # loop over "${array0[@]}" or "${array1[@]}" ...
echo " $j => ${ref[$j]}"
done
done
输出:
The array has 2 elements
A
Name => Bob's Computer
Uptime => 12hr
Serial => 123456
B
Name => Jeff's Computer
Uptime => 8hr
Serial => 789101
请注意bash
,它本身不支持数组数组,我们需要使用declare -n
语句来创建对变量的引用,这会降低代码的可读性。如果Python
是您的选择,请告诉我。它将更适合此类任务。
推荐阅读
- clips - 在 CLIPS 中获取规则体
- java - 如何在 Hibernate 中使用 @OneToOne 和 @Where?
- php - 如何在不访问电报机器人上的链接的情况下创建一个发出 http 请求的按钮
- html - 如何从spring boot中的设备列表中删除一个设备条目
- android - 左对齐按钮和底部导航栏顶部的 FAB
- android - 已发布的应用程序未出现在 Play 商店类别列表中
- java - 我在片段中编写 Listview 时遇到了麻烦
- sql-server - Outlook 加载项 - 连接到 SQL Server
- c - 如何声明具有 volatile 元素的静态数组?
- java - 如何使用 Java 将 JSONArray 转换为 R 数据框?