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"
This question already has answers here:
Output for loop to a file
(4 answers)
Loop and append/write to the same file without overwriting
(2 answers)
Closed 5 years ago.
I have a shell script that extracts certain values from a text file (input to it via the terminal). The script does the extraction as intended except, it doesn't print the output to the file correctly.
The script is:
#!/bin/bash
input_file=$1
while read -r LINE
do
IFS="=" read -r -a params <<< "$LINE"
if [ -n "${params[2]}" ]
then
IFS=" " read -r -a param_opcode <<< "${params[2]}"
echo "${param_opcode}"
fi
done < "$input_file"
The output on the terminal is as follows:
0xd2800140
0xd2800061
0x8b010000
0x8b000042
0xd1000821
0xd28001e5
0xd28000a6
0x9ac608a5
0xe7ff0010
0xe7ff0010
However, when I try to write this to a text file bu doing:
echo "${param_opcodes}" > log.txt
It prints only this to the file:
0xe7ff0010
I tried >> but I don't want to append to it. I want the file to be overwritten every time, I run the script.
Your redirection to log file isn't right because it's inside the while loop.
Use the redirection at the end of the while loop:
while read -r LINE; do
...
done < "$input_file" > "log.txt"
This question already has answers here:
Looping through the content of a file in Bash
(16 answers)
Closed 2 years ago.
I have the following .txt file:
Marco
Paolo
Antonio
I want to read it line-by-line, and for each line I want to assign a .txt line value to a variable. Supposing my variable is $name, the flow is:
Read first line from file
Assign $name = "Marco"
Do some tasks with $name
Read second line from file
Assign $name = "Paolo"
The following reads a file passed as an argument line by line:
while IFS= read -r line; do
echo "Text read from file: $line"
done < my_filename.txt
This is the standard form for reading lines from a file in a loop. Explanation:
IFS= (or IFS='') prevents leading/trailing whitespace from being trimmed.
-r prevents backslash escapes from being interpreted.
Or you can put it in a bash file helper script, example contents:
#!/bin/bash
while IFS= read -r line; do
echo "Text read from file: $line"
done < "$1"
If the above is saved to a script with filename readfile, it can be run as follows:
chmod +x readfile
./readfile filename.txt
If the file isn’t a standard POSIX text file (= not terminated by a newline character), the loop can be modified to handle trailing partial lines:
while IFS= read -r line || [[ -n "$line" ]]; do
echo "Text read from file: $line"
done < "$1"
Here, || [[ -n $line ]] prevents the last line from being ignored if it doesn't end with a \n (since read returns a non-zero exit code when it encounters EOF).
If the commands inside the loop also read from standard input, the file descriptor used by read can be chanced to something else (avoid the standard file descriptors), e.g.:
while IFS= read -r -u3 line; do
echo "Text read from file: $line"
done 3< "$1"
(Non-Bash shells might not know read -u3; use read <&3 instead.)
I encourage you to use the -r flag for read which stands for:
-r Do not treat a backslash character in any special way. Consider each
backslash to be part of the input line.
I am citing from man 1 read.
Another thing is to take a filename as an argument.
Here is updated code:
#!/usr/bin/bash
filename="$1"
while read -r line; do
name="$line"
echo "Name read from file - $name"
done < "$filename"
Using the following Bash template should allow you to read one value at a time from a file and process it.
while read name; do
# Do what you want to $name
done < filename
#! /bin/bash
cat filename | while read LINE; do
echo $LINE
done
Use:
filename=$1
IFS=$'\n'
for next in `cat $filename`; do
echo "$next read from $filename"
done
exit 0
If you have set IFS differently you will get odd results.
Many people have posted a solution that's over-optimized. I don't think it is incorrect, but I humbly think that a less optimized solution will be desirable to permit everyone to easily understand how is this working. Here is my proposal:
#!/bin/bash
#
# This program reads lines from a file.
#
end_of_file=0
while [[ $end_of_file == 0 ]]; do
read -r line
# the last exit status is the
# flag of the end of file
end_of_file=$?
echo $line
done < "$1"
If you need to process both the input file and user input (or anything else from stdin), then use the following solution:
#!/bin/bash
exec 3<"$1"
while IFS='' read -r -u 3 line || [[ -n "$line" ]]; do
read -p "> $line (Press Enter to continue)"
done
Based on the accepted answer and on the bash-hackers redirection tutorial.
Here, we open the file descriptor 3 for the file passed as the script argument and tell read to use this descriptor as input (-u 3). Thus, we leave the default input descriptor (0) attached to a terminal or another input source, able to read user input.
For proper error handling:
#!/bin/bash
set -Ee
trap "echo error" EXIT
test -e ${FILENAME} || exit
while read -r line
do
echo ${line}
done < ${FILENAME}
Use IFS (internal field separator) tool in bash, defines the character using to separate lines into tokens, by default includes <tab> /<space> /<newLine>
step 1: Load the file data and insert into list:
# declaring array list and index iterator
declare -a array=()
i=0
# reading file in row mode, insert each line into array
while IFS= read -r line; do
array[i]=$line
let "i++"
# reading from file path
done < "<yourFullFilePath>"
step 2: now iterate and print the output:
for line in "${array[#]}"
do
echo "$line"
done
echo specific index in array: Accessing to a variable in array:
echo "${array[0]}"
The following will just print out the content of the file:
cat $Path/FileName.txt
while read line;
do
echo $line
done
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
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