Bash read array from external file

I have a Bash script menu installed, which also requires user input. These inputs are written (appended to) to a text file named var.txt as follows:

input[0]='192.0.0.1' input[1]='username' input[2]='example.com' input[3]='/home/newuser' 

Now what I'm trying to accomplish is the ability to read from var.txt from a script like this:

 useradd var.txt/${input[1]} 

Now I know that it won’t work, just using it as an example.

Thanks Advance, Joe

+4
source share
3 answers

You can encapsulate the extraction of a variable in a function and take advantage of the fact that declare creates local variables when used inside a function. This method reads a file every time a function is called.

 readvar () { # call like this: readvar filename variable while read -r line do # you could do some validation here declare "$line" done < "$1" echo ${!2} } 

For a file named "data" containing:

 input[0]='192.0.0.1' input[1]='username' input[2]='example.com' input[3]='/home/newuser' foo=bar bar=baz 

You can do:

 $ a=$(readvar data input[1]) $ echo "$a" username $ readvar data foo bar 

This will read the array and rename it:

 readarray () { # call like this: readarray filename arrayname newname # newname may be omitted and will default to the existing name while read -r line do declare "$line" done < "$1" local d=$(declare -p $2) echo ${d/#declare -a $2/declare -a ${3:-$2}}; } 

Examples:

 $ eval $(readarray data input output) $ echo ${output[2]} example.com $ echo ${output[0]} 192.0.0.1 $ eval $(readarray data input) $ echo ${input[3]} /home/newuser 

By doing this this way, you will only need to make one function call, and the entire array will be available, and will not make separate requests.

+3
source

Use bash readarray statement . (This is the only way I can find to dynamically place spaces in the elements of an array.) You will need your var.txt file to just contain the elements of the array, one on each line, not containing assignments.

 readarray -t input < var.txt 

For more information, try help readarray (which will then tell you to try help mapfile ).

Here is my test:

 echo -e "a\nb c\nd" > var.txt readarray input < var.txt for item in "${input[@]}"; do echo $item; done 

prints:

 a bc d 

Note : doing cat var.txt | readarray -t input cat var.txt | readarray -t input does not work. I think this is because the input variable is limited out of reach.

+13
source

If the entire var.txt file contains only Bash- var.txt variable assignments, as you indicated, you can simply source it to make these variables available in the new Bash script:

 source var.txt useradd ${input[1]} 

This, however, will overwrite any existing variable with the same name. To do this, you can use command substitution by selecting certain variables:

 input[1]="$(grep '^input\[1\]=' var.txt | sed "s|[^=]*='\(.*\)'|\1|")" 

It allows you to rename variables, although you will have to do this for each variable of interest. It essentially extracts the value of the variable from the var.txt file and assigns it to the new variable. See the grep man page and sed man page for more details. information about their use.

Process substitution can allow simpler expressions:

 source <(grep '^input\[[0-9]*\]=' var.txt) useradd ${input[1]} 

This will allow you to import only definitions of interest, although you should keep an eye on reloading the unwanted variable.

+5
source

Source: https://habr.com/ru/post/1335466/


All Articles