Prefix and postfix elements of a bash array

前端 未结 5 1760
-上瘾入骨i
-上瘾入骨i 2020-12-14 16:13

I want to pre- and postfix an array in bash similar to brace expansion.

Say I have a bash array

ARRAY=( one two three )

I want to b

相关标签:
5条回答
  • 2020-12-14 16:19

    Your last loop could be done in a whitespace-friendly way with:

    EXPANDED=()
    for E in "${ARRAY[@]}"; do
        EXPANDED+=("prefix_${E}_suffix")
    done
    echo "${EXPANDED[@]}"
    
    0 讨论(0)
  • 2020-12-14 16:21

    For arrays:

    ARRAY=( one two three )
    (IFS=,; eval echo prefix_\{"${ARRAY[*]}"\}_suffix)
    

    For strings:

    STRING="one two three"
    eval echo prefix_\{${STRING// /,}\}_suffix
    

    eval causes its arguments to be evaluated twice, in both cases first evaluation results in

    echo prefix_{one,two,three}_suffix
    

    and second executes it. For array case subshell is used to avoid overwiting IFS

    You can also do this in zsh:

    echo ${${ARRAY[@]/#/prefix_}/%/_suffix}
    
    0 讨论(0)
  • 2020-12-14 16:22

    Bash brace expansion don't use regexes. The pattern used is just some shell glob, which you can find in bash manual 3.5.8.1 Pattern Matching.

    Your two-step solution is cool, but it needs some quotes for whitespace safety:

    ARR_PRE=("${ARRAY[@]/#/prefix_}")
    echo "${ARR_PRE[@]/%/_suffix}"
    

    You can also do it in some evil way:

    eval "something $(printf 'pre_%q_suf ' "${ARRAY[@]}")"
    
    0 讨论(0)
  • 2020-12-14 16:30

    I have exactly the same question, and I come up with the following solution using sed's word boundary match mechanism:

    myarray=( one two three )
    newarray=( $(echo ${myarray[*]}|sed "s/\(\b[^ ]\+\)/pre-\1-post/g") )
    echo ${newarray[@]}
    > pre-one-post pre-two-post pre-three-post
    echo ${#newarray[@]}
    > 3
    

    Waiting for more elegant solutions...

    0 讨论(0)
  • 2020-12-14 16:33

    Prettier but essentially the same as the loop solution:

    $ ARRAY=(A B C)
    $ mapfile -t -d $'\0' EXPANDED < <(printf "prefix_%s_postfix\0" "${ARRAY[@]}")
    $ echo "${EXPANDED[@]}"
    prefix_A_postfix prefix_B_postfix prefix_C_postfix
    

    mapfile reads rows into elements of an array. With -d $'\0' it instead reads null-delimited strings and -t omits the delimiter from the result. See help mapfile.

    0 讨论(0)
提交回复
热议问题