首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Shell脚本中将字符串变量中的值转换为Array

在Shell脚本中将字符串变量中的值转换为Array
EN

Stack Overflow用户
提问于 2022-01-21 12:22:09
回答 2查看 177关注 0票数 -2

我有一个字符串变量,可能有以下值的组合-

代码语言:javascript
复制
v="2020-01-2020-04,2020-11"

我想把上面的值转换成如下的数组-

代码语言:javascript
复制
array=(2020-01,2020-02,2020-03,2020-04,2020-11)

请任何人帮助我如何实现这一点,解释范围部分,并提取数组中相应的数据?

注意,字符串中的值是YYYY格式的Monthdate。

我试过用下面的代码来根据",“来分割,但是无法处理范围-

代码语言:javascript
复制
IN="2020-01-2020-04,2020-11"
arrIN=(${IN//,/ })
echo ${arrIN[1]}         
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-21 12:36:43

生成范围并将日期存储在bash数组中:

  • 首先定义一个将一个月添加到日期的函数:

代码语言:javascript
复制
next_month() {
    local y m
    IFS='-' read y m <<< "$1"
    if [ "$m" == 12 ]
    then
        m=1 y=$(( 10#$y + 1 ))
    else
        m=$(( 10#$m + 1 ))
    fi
    printf '%04d-%02d\n' "$y" "$m"
}

对于GNU date来说,这是微不足道的。

代码语言:javascript
复制
next_month() { date -d "$1-01 +1month" '+%Y-%m'; }

甚至是BSD date

代码语言:javascript
复制
next_month() { date -j -v '+1m' -f '%Y-%m' "$1" '+%Y-%m'; }

然后,

  • 在填充数组的主循环中使用它:

代码语言:javascript
复制
v="2020-01-2020-04,2020-11"

array=()
for date in ${v//,/ }
do
    [[ $date =~ ^([0-9]{4}-(0[1-9]|1[0-2]))(-([0-9]{4}-(0[1-9]|1[0-2])))?$ ]] || continue

    inidate=${BASH_REMATCH[1]}
    enddate=${BASH_REMATCH[4]:-$inidate}

    until [ "$inidate" == "$enddate" ]
    do
        array+=( "$inidate" )
        inidate=$(next_month "$inidate")
    done

    array+=( "$inidate" )
done

  • 和您将得到:

代码语言:javascript
复制
declare -p array
# declare -a array='([0]="2020-01" [1]="2020-02" [2]="2020-03" [3]="2020-04" [4]="2020-11")'
票数 1
EN

Stack Overflow用户

发布于 2022-01-21 13:19:41

bash中,请您尝试以下几种方法:

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

v="2020-01-2020-04,2020-11"

IFS=, read -ra a <<< "$v"       # split $v on comma(s) into an array a
for i in "${a[@]}"; do
    if [[ $i =~ ^[0-9]{4}-[0-9]{2}$ ]]; then
        array+=("$i")           # single YYYY-MM
    elif [[ $i =~ ^([0-9]{4})-([0-9]{2})-([0-9]{4})-([0-9]{2})$ ]]; then
                                # range of two YYYY-MM's
        if (( 10#${BASH_REMATCH[1]} != 10#${BASH_REMATCH[3]} )); then
            echo "the range of year not supported."
            exit 1
        else
            for (( j = 10#${BASH_REMATCH[2]}; j <= ${BASH_REMATCH[4]}; j++ )); do
                                # expand the range of months
                array+=( "$(printf "%04d-%02d" $((10#${BASH_REMATCH[1]})) "$j")" )
            done
        fi
    fi
done

(IFS=","; echo "${array[*]}")   # print the result

输出:

代码语言:javascript
复制
2020-01,2020-02,2020-03,2020-04,2020-11
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70801221

复制
相关文章

相似问题

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