我在执行命令后有一个字符串:
[username@hostname ~/script]$ gsql ls | grep "Graph graph_name"
- Graph graph_name(Vertice_1:v, Vertice_2:v, Vertice_3:v, Vertice_4:v, Edge_1:e, Edge_2:e, Edge_3:e, Edge_4:e, Edge_5:e)
那么我做了IFS=", " read -r -a vertices <<< "$(gsql use graph ifgl ls | grep "Graph ifgl(" | cut -d "(" -f2 | cut -d ")" -f1)"
将字符串拆分并追加到数组中。但是,我想用分隔符", "然后附加每个包含":v"的单词。对于一个数组,它的平均数包含":e"将被排除在外。
怎么做?不循环
像这样,使用grep
mapfile -t array < <(gsql ls | grep "Graph graph_name" | grep -oP 'bw+:v')
正则表达式匹配如下:
节点 | 说明 | |
---|---|---|
b | 字字符(w)和非字字符之间的边界 | |
w+ | 单词字符(a-z, a-z, 0-9, _)(1次或1次以上(匹配最多次数)) | |
:v | ':v' |
这个bash
脚本应该可以工作:
declare arr as array variable
arr=()
# use ", " as delimiter to parse the input fed through process substituion
while read -r -d ', ' val || [[ -n $val ]]; do
val="${val%)}"
val="${val#*(}"
[[ $val == *:v ]] && arr+=("$val")
done < <(gsql ls | grep "Graph graph_name")
# check array content
declare -p arr
输出:
declare -a arr='([0]="Vertice_1:v" [1]="Vertice_2:v" [2]="Vertice_3:v" [3]="Vertice_4:v")'
由于每个元素都有一个条件,因此逻辑上的方法是使用循环。可能有很多方法可以做到这一点,但这里有一个使用for循环的解决方案:
#!/bin/bash
input="Vertice_1:v, Vertice_2:v, Vertice_3:v, Vertice_4:v, Edge_1:e, Edge_2:e, Edge_3:e, Edge_4:e, Edge_5:e"
input="${input//,/ }" #replace , with SPACE (bash array uses space as separator)
inputarray=($input)
outputarray=()
for item in "${inputarray[@]}"; do
if [[ $item =~ ":v" ]]; then
outputarray+=($item) #append the item to the output array
fi
done
echo "${outputarray[@]}"
将输出:Vertice_1:v Vertice_2:v Vertice_3:v Vertice_4:v
由于元素中没有空格,所以可以使用