4

I'm trying to read 2 floating numbers from a very simple 1-line file in Bash. I want to store these two numbers into variables. All the examples I see from Googling look like:

while read VAR1 VAR2
do
   <command>
done < file.txt

But this keeps VAR1 and VAR2 inside the while loop only. How can I store the two variables so that I can use them anywhere in my script? Thanks so much!

4 Answers 4

9

The while loop is superfluous when reading a file with a single line (as described in your question ).

why not simply do :

read VAR1 VAR2 < file.txt
echo $VAR1
echo $VAR2

This would read the first line of your file

Sign up to request clarification or add additional context in comments.

Comments

2

dvhh's answer contains the crucial pointer:

If you're reading only a single line, there's no reason to use a while loop at all.

Your while loop leaves $VAR1 and $VAR2 empty, because the last attempt to read from the input file invariably fails due to having reached EOF, causing the variables to be set to the empty string.

If, by contrast, you truly needed to read values from multiple lines and needed to access them after the loop, you could use a bash array:

aVar1=() aVar2=() # initialize arrays
while read var1 var2
do
   aVar1+=( "$var1")
   aVar2+=( "$var2")
done < file.txt

# ${aVar1[@]} now contains all $var1 values, 
# ${aVar2[@]} now contains all $var2 values.

Note that it's good practice not to use all-uppercase names for shell variables so as to avoid conflicts with environment variables.

1 Comment

Yes, I probably should have added some comment about that while loop.
2

try this ...

#!/bin/bash

var1="unknown"
var2="unknown"

while read VAR1 VAR2
do
        var1=$VAR1
        var2=$VAR2
done < file.txt
echo "v1=$var1 v2=$var2"

Update: I think dvhh's answer is the correct one.

1 Comment

This is handy for retaining the values from the last iteration of the loop, but note that the OP mentions reading from a 1-line file, so there's no reason to use a loop in the first place.
0


first of you should obtain your separator in your script in this my example the uid and ... separate with ":"

 uid=$( IFS=":" ;while read uid   REST ; do  echo $uid  ; done </etc/passwd )
passwd=$( IFS=":" ;while read uid passwd   REST ; do   echo $passwd  ; done </etc/passwd )

IFS is internal field separator and default is white space and you should change it you can put script in varibale=$( script ) very good thing for scripting

you can see with

 echo $uid
echo $passwd

5 Comments

There's a lot of extraneous information in your answer that has no connection to the OP's question and makes it hard to understand the gist of your answer. Looks like you're demonstrating how to collect multiple values that a loop prints iteratively via a command substitution as a multi-line string. Given that the OP has stated that they read from a 1-line file, there is no need for such a fundamentally different approach (reading the same file twice, in a subshell, capturing via stdout), which can have side effects - simply not using a loop is the much simpler solution.
I recommend this method because scripting is not just simple syntax just test speed of run script with time ./script.sh >/dev/null this method has more speed and useful in scripting ,and in linux cause variable has not limitation for value we can put 10 even 15 meg in value like uid i tested it before
I have trouble understanding what you're saying, but in the case at hand the performance comparison is simple: read VAR1 VAR2 < file.txt is not only simpler, but will perform better than your command substitution-based approach (even if you only used a single command substitution).
@mklement0 i means when you put your script in variable speed of run shell script more than bash check line by line script just check that link
Yes, it's a good idea to avoid bash loops for performance reasons when possible (if I understand you correctly), but (a) generally, depending on your use case, that may not be an option, and (b), specifically, here: the solution to the OP's problem (as currently stated) is to not use a loop at all. As an aside: Do note that performance improvements would come from running a more efficient external utility that does the looping in a command substitution, whereas your example runs a slow bash loop in the command substitution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.