Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a problem with my bash array I was trying to read the file however the array allocated it in array[1] instead of 0

#!/bin/bash
index=0
INPUT=BookDB.txt
OLDIFS=$IFS
IFS=:
i=0
book=()
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read bookname author price quantity sold
do
#echo "BookName : $bookname"
#echo "Author : $author"
#echo "Price : $price"
#echo "Quantity : $quantity"
#echo "Sold : $sold"

    book+=("$bookname")
    author+=("$author")
    price+=("$price")
    quant+=("$quantity")
    sold+=("$sold") 

 done < $INPUT
 IFS=$OLDIFS



 # Use c style for loop
 # get total subscripts in an array
 total=${#book[*]}
 # 
 for (( i=0; i<=$(( $total -1 )); i++ ))
  do
   echo $i "${book[$i]} "
 done

 total=${#author[*]}
 # 
 for (( i=0; i<=$(( $total -1 )); i++ ))
 do
  echo  $i "${author[$i]} "
 done

Here is the output of the file

Book

0 Harry Potter - The Half Blood Prince 
1 The little Red Riding Hood 
2 Harry Potter - The Phoniex 
3 Harry Potter - The Deathly Hollow 
4 Little Prince 
5 Lord of The Ring 
6 Three Little Pig 
7 All About Ubuntu 
8 Catch Me If You Can 
9 Happy Day

Author

0  
1 J.K Rowling 
2 Dan Lin 
3 J.K Rowling 
4 Dan Lin 
5 The Prince 
6 Johnny Dept 
7 Andrew Lim 
8 Ubuntu Team 
9 Mary Ann 
10 Mary Ann 

Somehow the array for author[0] is empty

share|improve this question
5  
There's one namespace for scalar and array variables, and in bash and ksh, arrays just extend scalar variables. $author is ${author[0]}, author=x or read author is assigning to author[0]. Use different variable names in your read statement. –  Stéphane Chazelas Jan 27 at 13:08
    
Thank you yes it works. –  Lennon Chia Jan 27 at 13:13
1  
BTW, you'd be better off using perl or awk for that rather than bash loops and arrays. –  Stéphane Chazelas Jan 27 at 13:38
add comment

1 Answer

book is initialized to the empty array by the line book=(), so during the first run through the loop book+=("$bookname") sets the first element of the array book (i.e. ${book[0]}) to the first book name.

author is used sometimes as an array and sometimes as a scalar. In ksh and bash, when an array is referenced using a scalar syntax (i.e. anything other than ${VAR[INDEX]}), the first element of the array is used. Assigning to the variable in a way other than VAR=…, such as via the read builtin, sets the first element of the array. Conversely, if an array is expected, a scalar variable is treated as a one-word array. Thus:

  • On the first run through the loop, author contains the string J.K Rowling, then author+=("$author") sets it to a two-element array containing J.K Rowling twice.
  • On the second run through the loop, read sets ${author[0]} to Dan Lin, then author+=("$author") appends Dan Lin, yielding the three-element array ('Dan Lin' 'J.K. Rowling' 'Dan Lin').
  • On the last run, read sees an empty line, so it sets $bookname, ${author[0]} and the others to an empty string.

To fix this, use a different name for the loop variables and for the arrays where you accumulate the data.

titles=()
authors=()
prices=()
quantities=()
sales=()
while read title author price quantity sold
do
    titles+=("$title")
    authors+=("$author")
    prices+=("$price")
    quantities+=("$quantity")
    sales+=("$sold") 
 done < $INPUT
share|improve this answer
    
If your bash is new enough, there's a readarray command. –  Ricky Beam Jan 27 at 21:57
    
@RickyBeam readarray doesn't break the line into fields, so I don't see how it's useful here. –  Gilles Jan 27 at 22:04
    
Depends on the final purpose of his script. I don't see where 5 arrays are necessary, but we don't know what the final produce is supposed to do. –  Ricky Beam Jan 27 at 22:11
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.