How to read environment variable from the text file? [duplicate] - bash

This question already has answers here:
Forcing bash to expand variables in a string loaded from a file
(13 answers)
Closed 1 year ago.
Hi all, I'm facing an issue that I cant read the environment variable from the text file.
Here is the content of the text file:
Blockquote
#INCLUDE
$ward/ancd/qwe
.........
.........
And the bash script
while IFS= read -r line
do
echo "$line" # It shows $ward/ancd/qwe instead of tchung/folder/main/ancd/qwe
done < "$input"
Blockquote
It should directly shows "tchung/folder/main/ancd/qwe" when echo, but it outputs $ward/ancd/qwe.
The $ward is an environment variable and it able to shows the file path in bash when echo directly. But when comes to reading text file it cant really recognize the environment variable.
Blockquote
The current solution that i can think off is replace the matched $ENVAR in the $line with the value.
repo="\$ward"
if echo "$line" | grep -q "$repo"
then
# echo "match"
line="${line/$repo/$ward}"
#echo "Print the match line : $line"
fi
Is there any other more flexible way that can recognize the environment variables during reading file without replacing the substring one by one?

Perhaps you need to evaluate the content of $line within an echo:
while IFS= read -r line
do
echo $(eval "echo $line")
done

Use envsubst:
envsubst "$input"

Related

Shell that automatically trims spaces for no reason [duplicate]

This question already has answers here:
I just assigned a variable, but echo $variable shows something else
(7 answers)
Closed 3 months ago.
Introduction
I was trying to do some instructions on a file line by line with:
while IFS= read -r line; do
...
done < file
When I noticed that there was a problem with trailing whitespaces (for example: " a " => "a") that were automatically deleted, which is a real problem for me.
I searched in the documentation and didn't find any mention of that. And there is the same problem with printf.
Minimal example:
touch example # Create a file
echo " exa mple " >> example # Add some text
cat example # exa mple
echo $(cat example) # exa mple
rm example # Delete the file
In this example, I don't understand why echo $(cat example) doesn't have some trailing whitespaces.
And this "problem" is also here with:
while IFS= read -r line; do
echo $line # exa mple
done < example
Version:
Tested with:
zsh v5.9
bash v5.2.2
IFS= read -r line < file is correctly reading unmodified lines with leading and trailing spaces. You can confirm this by printing the variable using declare -p line.
But after you read the lines correctly, you are mangling them during your print commands. Both echo $(cat example) and echo $line have unquoted expansions, which cause the shell to word-split your lines.
Quote them to resolve the problem:
echo "$(cat example)"
echo "$line"
By the way, https://shellcheck.net/ is excellent for spotting and explaining errors like these.

Why would bash variables not expand in while loop [duplicate]

This question already has answers here:
Forcing bash to expand variables in a string loaded from a file
(13 answers)
Closed 3 years ago.
I have a little script that reads a json file:
{
"path": "$HOME/Projects:$HOME/Github"
}
I want to read path value, split on colon : and then read out the two paths with $HOME expanded.
#!/bin/sh
path_list="$(jq -r '.path' < "$JSON_FILE" | tr ':' '\n')"
echo "$path_list" | while IFS= read -r line; do
echo "$line"
done;
The output is not what I would expect:
$HOME/Projects
$HOME/Github
Yet when I run echo "$HOME/Projects" the $HOME parameter expands fine.
Initially, I thought that I needed double quotes around the variable so I tried echo "\"${line}\"" and that just prints "$HOME/projects". I am confused. Can anyone please shed some light on this for me or point to a good tutorial on bash parameter expansion?
Regarding another SO question addressing similar issue. I do not think this is the same because that OP was asking about expanding strings loaded from a file. I do not think that is the dominant concern in my question. Other responses to this question involve using eval which I would like to because users will be entering their own inputs. Other solutions rely on external packages like gettext. I believe there should be a straight forward answer here.
Solved by adding 'eval':
#!/bin/sh
path_list="$(jq -r '.path' < "$JSON_FILE" | tr ':' '\n')"
echo "$path_list" | while IFS= read -r line; do
eval echo "$line"
done;
More info: https://unix.stackexchange.com/questions/23111/what-is-the-eval-command-in-bash

Script: echoing lines from one file to another doesn't print '\t'. Issue [duplicate]

This question already has answers here:
Preserving leading white space while reading>>writing a file line by line in bash
(5 answers)
Closed 6 years ago.
I need to create a file by modifying some lines of a source one.
I developed a loop 'while read line; do'. Inside it, the lines I read and don't modify go just:
echo -e "$line" >> "xxxx.c"
My issue is that some of that lines start with '\t', and they won't print the output file.
Example:
while read line;
do
if echo "$line" | grep -q 'timeval TIMEOUT = {25,0};'
then
echo "$line"
fi
Any help? I've tried with the printf command also but without success.
In that case you could just remove "-e" argument from the echo command.
From echo man page:
-e enable interpretation of backslash escapes

shell bash, how to split a string to get the text after a tag [duplicate]

This question already has answers here:
shell parsing a line to look for a certain tag
(3 answers)
Closed 8 years ago.
I am trying to split a string to get the text after a string tag. I have been told using sed might be wise, but am unsure how to implement it.
I have the following text in a file:
/#text
/#difftext
....
I basically want to loop through to and get the text after the /#
Here is what I have so far:
while read line
do
if [[ ${line} == */#" ]]
#split line to get text
done < ${FILE}
grep -Po '/#\K.*'
or
sed 's#/###'
If you already have the line in a variable you can use string substitution:
$ line='/#text /#difftext ....'
$ echo ${line##*/#}
difftext ....
while read line
do
if [[ ${line} =~ ^.*/# ]]; then
echo ${line##*#}
fi
done <file

Reading files line by line in by using for loop bash script [duplicate]

This question already has answers here:
Looping through the content of a file in Bash
(16 answers)
Closed 3 years ago.
Say for example I have a file called "tests",it contains
a
b
c
d
I'm trying to read this file line by line and it should output
a
b
c
d
I create a bash script called "read" and try to read this file by using for loop
#!/bin/bash
for i in ${1}; do //for the ith line of the first argument, do...
echo $i // prints ith line
done
I execute it
./read tests
but it gives me
tests
Does anyone know what happened? Why does it print "tests" instead of the content of the "tests"? Thanks in advance.
#!/bin/bash
while IFS= read -r line; do
echo "$line"
done < "$1"
This solution can handle files with special characters in the file name (like spaces or carriage returns) unlike other responses.
You need something like this rather:
#!/bin/bash
while read line || [[ $line ]]; do
echo $line
done < ${1}
what you've written after expansion will become:
#!/bin/bash
for i in tests; do
echo $i
done
if you still want for loop, do something like:
#!/bin/bash
for i in $(cat ${1}); do
echo $i
done
This works for me:
#!/bin/sh
for i in `cat $1`
do
echo $i
done

Resources