First of all, I'm just an amateur at linux stuff..
I touch a bit of everything, I'm usually lucky enough to find what I'm searching for, but definitely not an advanced user or scripting master
The problem with that pseudo-array is you can't have spaces or it will treat as another variable.
But there's a workaround by specifying the Internal Field Separastor (IFS) the shell uses, which is a space by default.
For example, you could use a semicolon(; ), a colon(: ) or even a newline char, then the spaces would be no longer used as separators:
# Setting colon as separator
IFS=$':'
VAR="Hello there:I like fried chicken:With french fries"
# You also can put a \ to concatenate the next line (Avoiding inserting a new line),
# making easier to handle, insert and remove variables
VAR="\
Hello there:\
I like fried chicken:\
With french fries\
"
for i in $VAR; do
echo $i
done
# ./test
Hello there
I like fried chicken
With french fries
Of course you can't insert a variable that includes the same char you're using as separator.
But you can set the separator to basically anything.
For example, new line itself, making it even easier!
IFS=$'\n'
VAR="
Hello there
I like fried chicken
With french fries
"
# ./test
Hello there
I like fried chicken
With french fries
Following the first example, the added spaces caused some issues, requiring a bit of tweaking (Note the added apostrophe characters around ' $i ' ).
IFS=$'\n'
OPTS="
Option A
Option B
Option C
Option D
"
function init_array {
SZ=0
eval ARR=\$${VAR}S
for i in $ARR; do
eval "$VAR$SZ"='$i'
eval echo "New element: $VAR$SZ = \$$VAR$SZ"
SZ=$(($SZ + 1))
done
eval ${VAR}_SZ=$SZ
eval echo "Total elements in ${VAR}S: \$${VAR}_SZ"
}
echo "Testing variable OPTS"
VAR="OPT"; init_array
echo "First element: $OPT0"
eval echo "Last element: \$OPT$(($OPT_SZ - 1))"
# ./test2
Testing variable OPTS
New element: OPT0 = Option A
New element: OPT1 = Option B
New element: OPT2 = Option C
New element: OPT3 = Option D
Total elements in OPTS: 4
First element: Option A
Last element: Option D
Now all it takes is testing! That's what all this is about, experimenting, trial and error.
Eventually you'll get your script done.
The basics are dead easy:
- Create the variable with the initialization data called NAMES
- Create the pseudo-array by setting VAR='NAME', then calling init_array
- Directly accessing any element by NAMEn:
myvar="$NAME0"
echo "$NAME0"
- Indexed access using indexing number i (Requiring use of eval):
eval myvar="\$$NAME$i"
eval echo "\$$NAME$i"
- Finding a variable index, i.e. "Option C" on OPTS
i=0; while [ $i -lt $OPT_SZ ]; do
if [ "$(eval echo \$OPT$i)" == "Option C" ]; then
echo found \"Option C\" at index $i
fi
i=$(($i + 1))
done
found "Option C" at index 2
- Remember your variables are strings, so you can check whether any exists or not by checking if it's empty:
If exists:
if [ "$NAME0" ]; then
If it doesn't exist:
if [ -z "$NAME0" ]; then
Now the same with indexed method:
If exists:
if [ "$(eval echo \$NAME$i)" ]; then
If it doesn't exit:
if [ -z "$(eval echo \$NAME$i)" ]; then
The \ before $ basically disables the referencing.
So:
- $NAME tells the shell "Give the contents of the variable NAME"
- \$NAME writes literally "$NAME".
So, for NAME0="Thomas", i=0;
echo $NAME0 -> Show variable NAME0
>Thomas
echo $NAME$i -> Show variable NAME (Doesn't exist) and variable i(0)
>0
echo \$NAME$i -> Show text $NAME and variable i(0)
>$NAME0
eval echo \$NAME$i -> Evaluate "echo $NAME0", now it will show variable NAME0
>Thomas