目标:我尝试创建docker ps
的互动版本。基本上,每行都是一个"菜单"这样用户可以:启动,停止,ssh等。
示例:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1. bf4a9c7de6bf app_1 "docker-php-entryp..." 7 days ago Up About an hour 443/tcp, 0.0.0.0:80->80/tcp, 9000/tcp app_1
2. 26195f0764ce app_2 "sh /var/www/html/..." 10 days ago Up About an hour 443/tcp, 127.0.0.1:8000->80/tcp app_2
选择(1/2等)后,会有一个选项菜单,可以对所选容器执行各种操作。
问题:我似乎无法弄清楚如何解析docker ps
命令的每一行,以便我将容器ID和其他值作为数组元素。
到目前为止的代码:
list=`docker ps`
IFS=$'\n' array=($list)
for index in ${!array[@]}
do
declare -a 'a=('"${array[index]}"')'
printf "%s\n" "${a[@]}"
done
结果:
CONTAINER
ID
IMAGE
COMMAND
CREATED
STATUS
PORTS
NAMES
/usr/bin/dockersh: array assign: line 9: syntax error near unexpected token `>'
/usr/bin/dockersh: array assign: line 9: `bf4a9c7de6bf app_1 "docker-php-entryp..." 7 days ago Up About an hour 443/tcp, 0.0.0.0:80->80/tcp, 9000/tcp app_1'
答案 0 :(得分:3)
看起来你引用了一些问题,也许可以试试:
list=$(docker ps)
IFS=$'\n' array=($list)
for index in "${!array[@]}"
do
declare -a a=("${array[index]}")
printf "%s\n" "${a[@]}"
done
如果没有正确引用,你的字符串可能会被重新分割;考虑检查你的shell脚本@ shell-check.net,因为它通常会给你一些关于错误语法的好提示。
答案 1 :(得分:1)
如果您想要一个具有矩阵的关联数组,其中所有docker ps
字段都可以在行/列中访问,则可以使用awk
在字段之间插入分隔符|
。然后将结果导出到单个关联数组中,并根据您期望的列数构建矩阵(例如7):
#!/bin/bash
IFS=$'|'
data=$(docker ps -a | awk '
function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s }
{
if (NR == 1) {
head[1] = index($0,"CONTAINER ID")
head[2] = image=index($0,"IMAGE")
head[3] = command=index($0,"COMMAND")
head[4] = created=index($0,"CREATED")
head[5] = status=index($0,"STATUS")
head[6] = ports=index($0,"PORTS")
head[7] = names=index($0,"NAMES")
}
else{
for (i = 1;i < 8;i++) {
if (i!=7){
printf "%s",rtrim(substr($0, head[i], head[i+1] - 1 - head[i])) "|"
}
else{
printf "%s",rtrim(substr($0, head[i], 100)) "|"
}
}
print ""
}
}')
arr=($data)
max_column=7
row=0
column=0
declare -A matrix
for index in "${!arr[@]}"
do
matrix[$row,$column]=$(echo "${arr[index]}" | tr -d '\n')
column=$((column+1))
if [ $((column%max_column)) == 0 ]; then
row=$((row+1))
column=0
fi
done
echo "first container ID is : ${matrix[0,0]}"
echo "second container ID is : ${matrix[1,0]}"
echo "third container NAME is : ${matrix[2,6]}"
在awk
部分中,目的是在每个字段之间插入|
字符,以便将数据注入到具有|
分隔符的关联数组中
当字段内容与字段标题对齐时,我们将每个字段名称的索引存储在head
数组中,并根据下一个字段位置提取每个字段修剪
然后根据最大列数(7)构建matrix
。然后可以使用${matrix[row,column]}
答案 2 :(得分:0)
常见故事...除非您确切知道格式以及如何控制它,否则不要使用for循环读取数据:
while IFS="\n" read -r line
do
array+=("$line")
done< <(docker ps)
就我个人而言,我会尝试从行的开头(1.,2。等)中删除数字,因为这样你就可以把它扔进一个选择中它会给你数字,然后可以用它来引用相关的项目