5

I have a text file named sqlfile, with the following content:

a.sql
b.sql
c.sql
d.sql

What I want is that to store them in variables and then print using for loop. But here I get only d.sql in the output of the script.

The script:

#!/bin/bash

while read line
do
files=`echo $line`
done < /home/abdul_old/Desktop/My_Shell_Script/sqlfile

for file in $files
        do
                echo $file
        done

6 Answers 6

6

A variable can only hold one element, what you want is an array

#!/bin/bash

while read line
do
  files+=( "$line" )
done < /home/abdul_old/Desktop/My_Shell_Script/sqlfile

for file in "${files[@]}"
do
  echo "$file"
done
Sign up to request clarification or add additional context in comments.

Comments

5
while read line
do files="$files $line"
done < /home/abdul_old/Desktop/My_Shell_Script/sqlfile

or

files=$(</home/abdul_old/Desktop/My_Shell_Script/sqlfile)

or

files=$(cat /home/abdul_old/Desktop/My_Shell_Script/sqlfile)

You're doing way too much work in your loop.

The middle alternative works with bash; the other two work with most shells. Prefer $(...) to back-quotes.

This code assumes there are no spaces in file names to mess things up. If you do use blanks in file names, you have to work marginally harder - see the array-based solution by SiegeX

Comments

0

I think you need to make the "files" as array. otherwise, as soon as the while finishes, "files" stores the latest "line". try:

files=( "${files[@]}" $line )

Comments

0

That's right, you assifn last value to "files"

You must use for instance += instead of =

#!/bin/bash

while read line
do
files+=`echo " $line"`
done < /home/abdul_old/Desktop/My_Shell_Script/sqlfile

for file in $files
        do
                echo $file
        done

4 Comments

You don't need the first echo; you could perfectly well use files+=" $line" and it would be simpler and more efficient (no subshell).
@AbdulManaf: are you using bash? Which version of bash (find out with bash --version).
GNU bash, version 4.1.5(1)-release (i686-pc-linux-gnu)
I use GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu), and += works for me. But the point is -- you must not reassign the variable. You need to add new value. If += doesn't work for you , you can try for instance files="$files $line"
0

Using read is fine but you have to set the IFS environment variable first else leading and trailing white space are removed from each line: Preserving leading white space while reading>>writing a file line by line in bash.

Comments

0

All you have to do is:

readarray myData < sqlfile

This will put file lines into an array called myData
Now you can access any of these lines like this:

printf "%s\n" "${myData[0]}" #outputs first line
printf "%s\n" "${myData[2]}" #outputs third line

And you can iterate over it:

for curLine in "${myData[@]}"; do
    echo "$curLine"
done

Note that these lines would contain \n character as well. To remove trailing newlines you can use -t flag like this:

readarray -t myData < sqlfile

readarray is a synonym to mapfile. You can read about it in man bash

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.