首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从数值范围生成自定义字符串并将其保存到bash中的数组中。

从数值范围生成自定义字符串并将其保存到bash中的数组中。
EN

Stack Overflow用户
提问于 2018-06-20 19:36:23
回答 1查看 76关注 0票数 1

bash脚本中有一个字符串,如下所示:

代码语言:javascript
复制
 nodeParts="node[0-2]\n node[3-5]"

(中间由换行符分隔的字符串)。我需要做的是扩大这些数字,并将其分别放在一个数组中。扩大的结果如下:

代码语言:javascript
复制
 node_array[0]=node0
 node_array[1]=node1
 node_array[2]=node2
 node_array[3]=node3
 node_array[4]=node4
 node_array[5]=node5

我使用awk命令来实现这一点,但是代码既不优雅也不高效。守则如下:

代码语言:javascript
复制
 node_array[0]=""
 count=0
 for node in $nodeParts
 do
      #first isolate the 'node' word
      base=$(echo "$node" | awk 'BEGIN{FS="["}{printf("%s\n",$1);}END{}')
      base=$(echo -e "$base" | tr -d '[:space:]')  

      #now use awk twice to isolate the characters between [ and ]      
      numbers=$(echo "$node" | awk 'BEGIN{FS="["}{printf("%s\n",$2);}END{}')
      numbers=$(echo "$numbers" |  awk 'BEGIN{FS="]"}{printf("%s\n",$1);}END{}')

      #now break the isolated [] by - to get the start and end numbers
      begin=$(echo "$numbers" | awk 'BEGIN{FS="-"}{printf("%s\n",$1);}END{}')
      begin=$(echo -e "$begin" | tr -d '[:space:]') #in case there is white space


      end=$(echo "$numbers" | awk 'BEGIN{FS="-"}{printf("%s\n",$2);}END{}')
      end=$(echo -e "$end" | tr -d '[:space:]')

      #use a while loop to add it to the node_array
      while [ $begin -le $end ]
      do
              node_array[$count]="$base$begin"
              ((count++))
              ((begin++))
      done
 done

正如您所看到的,它是一个非常基本的实现。而我所知道的就是。如果您能帮助我改进这段代码,使其更高效、更小,我将不胜感激。

-ppgoodman。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-20 19:59:41

正如Charles Duffy所提到的,没有POSIX内置程序可以直接执行。因为shell将路径名展开应用于模式node[0-2],并在存在时查找node0node2的文件,或者如果不存在此类文件,则将其保留为未展开的glob。因此,要解决您的用例,需要将它们看作是固定的字符串,而不是全局模式。

如果涉及到一些bash,您可以编写一个如下所示的脚本

代码语言:javascript
复制
#!/usr/bin/env bash

read -r -d '' nodeParts << EOM
node[0-2]
node[3-5]
EOM

mapfile -t tempNodeArray <<<"$nodeParts"

# The part up to here is user's choice on how to pass the input
# The example below uses a way to store the multi line string 
# using a heredoc and later passes that to an array by using
# mapfile 

# Defining a regex to match the 'node[digit1-digit2]' part
regex='node\[([[:digit:]]+)-([[:digit:]]+)\]'

# The final array where the output will be stored
nodeArray=()

# For each of the entry in array, do a regex match to extract
# the numbers
for entry in "${tempNodeArray[@]}"; do
    # Take the captured groups on successful regex match and 
    # make a loop over the numbers
    if [[ $entry =~ $regex ]]; then
        start="${BASH_REMATCH[1]}"
        stop="${BASH_REMATCH[2]}"
        for((i=start; i<=stop; i++)); do
            # Adding to the array prefixing with 'node-'
            nodeArray+=( node"$i" )
        done
    fi
done

# Print the final array to see how its stored, also printf '%s\n' "${nodeArray[@]}"
declare -p nodeArray
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50955831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档