1

In the below shell script, I'm trying to conditionally add elements to an array which is syntactically incorrect when checked in shellcheck.

#!/bin/bash

echo "Hello World";
HH=1

ARR=(
    "a"
    "b"
    "c"
    if [ ${HH} = 1 ]; then
        "f"
    else
        "g"
    fi
    "d"
    "e"
)

for arr in "${ARR[@]}"; do
    echo "${arr}"
done

ShellCheck Error:

Line 6:
ARR=(
^-- SC1009 (info): The mentioned syntax error was in this variable assignment.
    ^-- SC1073 (error): Couldn't parse this array assignment. Fix to allow more checks.
 
Line 12:
    if [ ${HH} = 1 ]; then
                    ^-- SC1072 (error): Expected ) to close array assignment. Fix any mentioned problems and try again.
0

2 Answers 2

4

Keep it simple and set a variable to the value you want to use in the array:

if [[ "$HH" == 1 ]]; then
    foo="f"
else
    foo="g"
fi

ARR=(
    "a"
    "b"
    "c"
    "$foo"
    "d"
    "e"
)
Sign up to request clarification or add additional context in comments.

3 Comments

It's worth noting that this is much more efficient than the subshell in the other answer's first example (which forks off a subprocess to run the if)
What if there is no else part? I mean add element to the array only if HH=1, otherwise don't
@Harry Chameleon Questions are strongly discouraged on this forum, just ask a new question if you have new requirements after people have posted answers to the question you asked.
2

How to conditionally add elements to an array in shell script

Here are some examples:

HH=1
ARR=(
    "a"
    "b"
    "c"
    "$(if [[ ${HH} == 1 ]]; then echo f; else echo g; fi)"
    "d"
    "e"
)
HH=1
lookup=([0]=g [1]=f)
ARR=(
    "a"
    "b"
    "c"
    "${lookup[HH]}"
    "d"
    "e"
)
HH=1
ARR=(
    "a"
    "b"
    "c"
    "d"
    "e"
)
if [[ ${HH} == 1 ]]; then
   ARR+=(f)
else
   ARR+=(g)
if
# insert element $3 at position $2 in array $1
array_insert() {
    local -n _arr="$1" || return 2
    _arr=("${_arr[@]::$2}" "${@:3}" "${_arr[@]:$2}")
}
HH=1
ARR=(
    "a"
    "b"
    "c"
    "d"
    "e"
)
if [[ ${HH} == 1 ]]; then
   array_insert ARR 3 f
else
   array_insert ARR 3 g
if
HH=1
ARR=(
    "a"
    "b"
    "c"
)
if [[ ${HH} == 1 ]]; then
   ARR+=("f")
else
   ARR+=("g")
if
ARR+=(
    "d"
    "e"
)

In case there is only if part the array contains an empty string element. How do I fix that? For e.g; "$(if [ "${HH}" = 1 ]; then echo "d"; fi)", this adds an empty string element to the array if HH=0

If you are fine with ignoring shellcheck error https://www.shellcheck.net/wiki/SC2046 , then remove the quotes around the $(..) expression. Unquoted command substition will result in executing word splitting (and filename expansion) over the result, effectively replacing an empty string with no words resulting in no items. However this might not work with a string with spaces, * ? [ characters in the resulting string. In such cases, use other presented method. See also https://mywiki.wooledge.org/WordSplitting , https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html .

HH=1
ARR=(
    "a"
    "b"
    "c"
    $(if [[ ${HH} == 1 ]]; then echo f; fi)
    "d"
    "e"
    # pitfalls:
    $(if [[ ${HH} == 1 ]]; then echo "a b c"; fi)  # adds 3 elements
    $(if [[ ${HH} == 1 ]]; then echo "'a b c'"; fi)  # also adds 3 elements, it is just not possible to quote "inside"
    $(if [[ ${HH} == 1 ]]; then echo "*"; fi)  # expands *, adds all files in PWD
)

There is no need to do if [ ! ${#ARR[@]} -eq 0 ]; then. When array is empty, "${ARR[@]}" is nothing, so the loop will not run at all.

5 Comments

Why not use lookup=(g f) instead of lookup=([0]=g [1]=f)
There is no reason.
In case there is only if part the array contains an empty string element. How do I fix that? For e.g; "$(if [ "${HH}" = 1 ]; then echo "d"; fi)", this adds an empty string element to the array if HH=0
If you are fine with ignoring shellcheck warning, then remove the quotes from the expression. Unquoted command substition will result in executing word splitting (and filename expansion) over the result, effectively replacing an empty string with no words resulting in no items. So just $(if [ "${HH}" = 1 ]; then echo "d"; fi). However it might not work with a string with spaces, * ? [ characters in the d string. In such cases, use other presented method.
I adited the answer and added this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.