Bash Array não armazena corretamente

1

Eu tenho um problema com o meu array bash que eu estava tentando ler o arquivo, mas o array alocou-o em array [1] ao invés de 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

Aqui está a saída do arquivo

Livro

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

Autor

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 

De alguma forma, a matriz para o autor [0] está vazia

    
por Len 27.01.2014 / 13:54

1 resposta

2

book é inicializado na matriz vazia pela linha book=() , portanto, durante a primeira execução do loop book+=("$bookname") , o primeiro elemento da matriz book (ou seja, ${book[0]} ) é definido para o primeiro livro nome.

author é usado às vezes como uma matriz e às vezes como escalar. Em ksh e bash, quando uma matriz é referenciada usando uma sintaxe escalar (ou seja, qualquer coisa diferente de ${VAR[INDEX]} ), o primeiro elemento da matriz é usado. Atribuir à variável de maneira diferente de VAR=… , como por meio do read builtin, define o primeiro elemento da matriz. Por outro lado, se uma matriz é esperada, uma variável escalar é tratada como uma matriz de uma palavra. Assim:

  • Na primeira execução do loop, author contém a string J.K Rowling e, em seguida, author+=("$author") a define como uma matriz de dois elementos contendo J.K Rowling duas vezes.
  • Na segunda execução do loop, read define ${author[0]} a Dan Lin , então author+=("$author") anexa Dan Lin , gerando a matriz de três elementos ('Dan Lin' 'J.K. Rowling' 'Dan Lin') .
  • Na última execução, read vê uma linha vazia, por isso define $bookname , ${author[0]} e os outros como uma string vazia.

Para corrigir isso, use um nome diferente para as variáveis de loop e para as matrizes onde você acumula os dados.

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
    
por 27.01.2014 / 22:52

Tags