How to Manipulate Array in Shell Script

how to manipulate array in shell script

When settings data in array does not recall with $:

declare -a FILES
file_count=0
if [ "$file_ext" != "$SUPPORTED_FILE_TYPE" ] ; then
echo "$file_ext is not supported for this task."
else
FILES[$file_count]=$filename
file_count=$file_count+1
fi

FILES without $.


This works for me:

#!/bin/bash
declare -a FILES
file_count=0

file_ext='jpg'
SUPPORTED_FILE_TYPE='jpg'
filename='test.jpg'

if [ "$file_ext" != "$SUPPORTED_FILE_TYPE" ] ; then
echo "$file_ext is not supported for this task."
else
FILES[$file_count]=$filename
file_count=$(($file_count+1))
fi

As you see, a little modification $(( )) for math operation, but the FILES assignements is the same...


As pointed out after lots of tests, Ubuntu default shell seems to be dash, which raised the error.

Bash shell Array manipulation

No way. I wrote this code just yesterday to iterate over an array.

line="This is line1 of file1 with 10 words."
words=($line)
for word in ${words[@]};
do
echo "Word: $word"
done

Output:

Word: This
Word: is
Word: line1
Word: of
Word: file1
Word: with
Word: 10
Word: words.

Bash Array Manipulation

Maybe this example can help you

#!/bin/bash

while read -r line; do
#Creating one big Array with all the values from the arrays file
Array+=(`grep -oP '\(\K(.+?)(?=\))' <<< "$line"`)
done < JeopardyOut

echo "Giant Array value: ${Array[@]}"

# Or you can clone the arrays in the file

i=0
while read -r line; do
((i++))
eval "T$i=(`grep -oP '\(\K(.+?)(?=\))' <<< "$line"`)"
done < JeopardyOut

echo "This is the contents of array T1: ${T1[@]}"
echo "This is the contents of array T2: ${T2[@]}"
echo "This is the contents of array T3: ${T3[@]}"
echo "This is the contents of array T4: ${T4[@]}"
echo "This is the contents of array T5: ${T5[@]}"

# This can help you to make a new file
# I change some value to our arrays

T1[2]=0
T2[1]=true

# Now let's go to make a new arrays file

echo "T1=(${T1[@]})" > JeopardyOut2
echo "T2=(${T2[@]})" >> JeopardyOut2
echo "T3=(${T3[@]})" >> JeopardyOut2
echo "T4=(${T4[@]})" >> JeopardyOut2
echo "T5=(${T5[@]})" >> JeopardyOut2

echo "This is the content of JeopardyOut2:"

cat JeopardyOut2

Output

$ bash example
Giant Array value: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
This is the contents of array T1: 1 1 1 1 1
This is the contents of array T2: 1 1 1 1 1
This is the contents of array T3: 1 1 1 1 1
This is the contents of array T4: 1 1 1 1 1
This is the contents of array T5: 1 1 1 1 1
This is the content of JeopardyOut2:
T1=(1 1 0 1 1)
T2=(1 true 1 1 1)
T3=(1 1 1 1 1)
T4=(1 1 1 1 1)
T5=(1 1 1 1 1)
$

How to change values of bash array elements without loop

Use Parameter Expansion:

array=("${array[@]/#/^}")

From the documentation:

${parameter/pattern/string}


Pattern substitution. The pattern is expanded to produce a pattern just as in pathname
expansion. Parameter is expanded and the longest match of pattern against its value is
replaced with string. If pattern begins with /, all matches of pattern are replaced with
string. Normally only the first match is replaced. If pattern begins with #, it must
match at the beginning of the expanded value of parameter. If pattern begins with %, it
must match at the end of the expanded value of parameter. If string is null, matches of
pattern are deleted and the / following pattern may be omitted. If parameter is @ or *,
the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the
substitution operation is applied to each member of the array in turn, and the expansion is
the resultant list.

Add a new element to an array without specifying the index in Bash

Yes there is:

ARRAY=()
ARRAY+=('foo')
ARRAY+=('bar')

Bash Reference Manual:

In the context where an assignment statement is assigning a value to a shell variable or array index (see Arrays), the ‘+=’ operator can be used to append to or add to the variable's previous value.

Also:

When += is applied to an array variable using compound assignment (see Arrays below), the variable's value is not unset (as it is when using =), and new values are appended to the array beginning at one greater than the array's maximum index (for indexed arrays)

Manipulating an array (printed by php-cli) in shell script

You should debug your PHP script first to produce the valid array content, code

print $associativeArray;

will just get you the following output:

$ php test.php 
Array

You can simply print the associative array in a foreach loop:

foreach ( $associativeArray as $key=>$val ){
echo "$key:$val\n";
}

giving a list of variable names + content separated by ':'

$ php test.php 
BASE_PATH:1
db_host:2
db_name:3
db_user:4
db_pass:5

As for the shell script, I suggest using simple and understandable shell constructs and then get to the advanced ones (like ${#result}) to use them correctly.

I have tried the following bash script to get the variables from PHP script output to shell script:

# set the field separator for read comand
IFS=":"

# parse php script output by read command
php $PWD'/test.php' | while read -r key val; do
echo "$key = $val"
done

How to create an associate array with value of a list of items in bash

Edit: take comments into account and replace now useless arrays by scalar strings.

As you want to set bash variables in the command's context we cannot execute them with "$cmd", this would not work for variable assignments. The following uses eval, which is extremely risky, especially if you do not fully control the inputs. A better solution, but more complicated, would be to use other variables for the execution environment, declare functions to limit the scope of variables and/or restore them afterwards, use eval only in last resort and only after sanitizing its parameters (printf '%q')... Anyway, you have been warned.

Storing bash commands and their arguments in variables is not recommended. But if you really need this it would be better to store the command names and the full commands in 2 different variables. They could be associative arrays or, if your bash is recent enough and supports namerefs, scalar variables named from your keys (if they are valid bash variable names).

Example where the key is stored in bash variable k, and the command is the second of your own example, plus some dummy arguments:

k="e"
# add a new command with key "$k"
declare -n cmd="${k}_cmd" lcmd="${k}_lcmd"
cmd="dolphin"
lcmd="XDG_CURRENT_DESKTOP=KDE dolphin arg1 arg2 'arg 3'"
...
# launch command with key "$k"
declare -n cmd="${k}_cmd" lcmd="${k}_lcmd"
if not_running "$cmd"; then
eval "$lcmd"
fi

Demo with key foo, command printf and arguments '%s\n' 'a b' 'c d':

$ k="foo"
$ declare -n cmd="${k}_cmd" lcmd="${k}_lcmd"
$ cmd="printf"
$ lcmd="printf '%s\n' 'a b' 'c d'"
$ eval "$lcmd"
a b
c d

change array value while looping in bash

Because of the first space = is not interpreted as an assignment. There is a full explanation on So.

Btw ${SourceFolder[$i]} evaluate the array element, which is not what you want to do. For instance for the first one it is the empty string.

Replaces with SourceFolder[$i]=



Related Topics



Leave a reply



Submit