LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   problem with arrays in bash (https://www.linuxquestions.org/questions/linux-newbie-8/problem-with-arrays-in-bash-719893/)

igor.R 04-17-2009 12:33 PM

problem with arrays in bash
 
Hi everybody, I have a problem with the bash script (see below)

I want to write contents of the log file into an array
with one line per element.

======================================================================

Code:

declare -a myarray

let count=0
tail -n20 "myfile.log" | while read tmpline
do
  myarray[$count]="$tmpline"
  let count=count+1
done

echo "N. of elements:"${#myarray[@]}

echo "Array contents:"${myarray[@]}

======================================================================

and as a result I get zero elements and empty array.
(myfile.log is not empty)

What am I doing wrong? :scratch:

blackhole54 04-17-2009 06:59 PM

The problem is that when you use a pipe you create a subprocess. So the while loop is running as a subprocess and the array elements you assign never get "seen" by the parent. You can have the while loop run in the same process as the rest of the script by using redirection like so:

Code:

while read variable list; do
# insert  body of loop here
done < file

There is a capability in bash called Process Substitution (see the man page) which I thought should remove the necessity of a creating a temporary file just to redirect into the loop. But I have never been able to make it work. (If you or somebody else can explain how to use that with a while loop, I'd love to hear it.)

Robhogg 04-17-2009 07:12 PM

Or you could use:
Code:

for tmpline in $(tail -n20 "myfile.log")
do
...

Sorry - blackhole 54 pointed out my obvious mistake below :redface:

blackhole54 04-17-2009 07:21 PM

@Robhogg

Wouldn't spaces in the contents of myfile.log cause problems? I.e. each "word" would be separate instance of $tmpline?

igor.R 04-17-2009 08:05 PM

Quote:

Originally Posted by igor.R (Post 3512421)
Hi everybody, I have a problem with the bash script (see below)

I want to write contents of the log file into an array
with one line per element.

======================================================================

Code:

declare -a myarray

let count=0
tail -n20 "myfile.log" | while read tmpline
do
  myarray[$count]="$tmpline"
  let count=count+1
done

echo "N. of elements:"${#myarray[@]}

echo "Array contents:"${myarray[@]}

======================================================================

and as a result I get zero elements and empty array.
(myfile.log is not empty)

What am I doing wrong? :scratch:


I have found solution here

Code:

declare -a myarray

let count=0
while read tmpline
do
  myarray[$count]="$tmpline"
  let count=count+1
done < <(tail -n20 "myfile.log" && echo " ")


echo "N. of elements:"${#myarray[@]}

echo "Array contents:"${myarray[@]}

works for me

PTrenholme 04-17-2009 08:29 PM

The line: done < <(tail -n20 "myfile.log" && echo " ") does not look (to me) to be syntactically correct.
I think that done << $(tail -n20 "myfile.log" && echo " ") might work better, but Jeremy has installed a new "redface" icon for me to use if (when?) I'm wrong (again).

igor.R 04-17-2009 08:38 PM

Quote:

Originally Posted by PTrenholme (Post 3512778)
The line: done < <(tail -n20 "myfile.log" && echo " ") does not look (to me) to be syntactically correct.
I think that done << $(tail -n20 "myfile.log" && echo " ") might work better, but Jeremy has installed a new "redface" icon for me to use if (when?) I'm wrong (again).

The space between the first < and second < is mandatory! Although, it should be noted that, between the two <'s, you can have as many spaces as you want. You can even use a tab between the two <'s, they just can't be directly connected.

blackhole54 04-18-2009 12:27 AM

Thanks igor.R,

That's the answer I was looking for. My reading of the man page led me to believe that the first "<" wasn't necessary. Obviously it is.

PTrenholme 04-18-2009 11:05 AM

Quote:

Originally Posted by igor.R (Post 3512788)
The space between the first < and second < is mandatory! Although, it should be noted that, between the two <'s, you can have as many spaces as you want. You can even use a tab between the two <'s, they just can't be directly connected.

O.K., as I said: :redface:


All times are GMT -5. The time now is 07:37 AM.