Reputation: 43
I want to read variable name from txt file in bash script.
For example
I run var="thanks"
in terminal
I create file.txt and txt file contains $var
I create variable var2
in terminal. var2=""
Then I run var2=$(<file.txt)
command in terminal.
The Problem is
$ echo $var2
"$var"
I want the output of the echo $var
command to be "thanks"
$ echo $var2
"thanks"
So what should I do?
Upvotes: 3
Views: 1173
Reputation: 70722
${!var}
indirect expansion:Anoter way for dropping $"
if present:
IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Tests:
var=Hello\ world\!
echo '"$var"' >file.txt
cat file.txt
"$var"
IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Hello world!
echo 'var' >file.txt
cat file.txt
var
IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Hello world!
IFS
Input Field Separator (usually contain: $' \t\n'
<space><tab><newline>
). All characters in this field are treated as field separator, so don't appear in array.
IFS='..' read ..
when variable definition prepend command, variable are only affected for this execution
-a var2
read make var2
an array. Use declare -p
to show his content:
IFS='$"' read -a var2 <file.txt
declare -p var2
declare -a var2=([0]="" [1]="" [2]="var")
${var2[*]}
will merge var
's fields in a single string, separated by 1st $IFS
character.
echo "<${var2[*]}>"
< var>
var2=( foo bar baz )
will redefine var2
ignoring spaces (as any characters in $IFS
)
var2=(${var2[*]}) # This step become useless, in 2nd case, but harmless.
declare -p var2
declare -a var2=([0]="var")
${!var2}
is known as indirect expansion
echo ${!var2}
Hello world!
declare -n name=value
make NAME a reference to the variable named by its value
IFS='$"' read -a var2 < file.txt
var2=(${var2[*]})
declare -p var2
declare -a var2=([0]="var")
declare -n var3=$var2
echo $var3
Hello world!
local -n
in a function:readFrom() {
local var2
IFS='$"' read -a var2 < $1
var2=(${var2[*]})
local -n target=$var2
echo $target
}
Then
echo '"$var"' >file.txt
var=Hello\ world\!
readFrom file.txt
Hello world!
readFrom() {
local var2
IFS='$"' read -a var2 < $1
var2=(${var2[*]})
local -n target=$var2 result=${2:-INPUT}
result=("$target")
}
Then
readFrom file.txt newvar
echo "$newvar"
Hello world!
Advantage of this:
Upvotes: 1
Reputation: 241758
If you put just var
into the file without the $
and quotes, you can use variable indirection.
var2=$(< file.txt)
var2=${!var2}
echo $var2
Or, if you need the dollar sign and quotes, remove them using parameter expansion before applying the indirection
var2=$(< file.txt)
var2=${var2#'"$'}
var2=${var2%\"}
var2=${!var2}
echo $var2
Upvotes: 3