0

Example File

oj Orange Juice

10 100

A half gallon of orange juice.

This is what I did and it worked

while read -r simpleName itemName; do
        read currentQuantity maximumQuantity
        read description

        echo "Item Name: $itemName"
        echo "Simple Name: $simpleName"
        echo "Item Number: $itemNumber"
        echo "Qty: $currentQuantity/$maximumQuantity"
        echo "Description: $description"
    done < $FILE

Note: Item number is prompted from the user prior to this and it determines which file to open.

This while loop correctly reads the file, stores the variables, and gives the desired output. The issue is, I used this same exact while loop two more times and it's not working. For some reason in the other two scenarios, simpleName and itemName are coming up blank, but the rest are working correctly.

Here's an example of where it is NOT working

#!/bin/bash

echo ""
read -p "Enter an item number: " itemNumber
echo ""

FILE="./data/${itemNumber}.item"
date=`date "+%Y-%m-%d %H:%M:%S"`

if test -f $FILE; then

    if test -f ./data/queries.log; then
        echo "DELETED: $date - $simpleName" >> ./data/queries.log
    else
        > ./data/queries.log
        echo "DELETED: $date - $simpleName" >> ./data/queries.log
    fi

    while read -r simpleName itemName; do
        read currentQuantity maximumQuantity
        read description
    done < $FILE

    rm $FILE

    echo "$simpleName was successfully deleted."
else
    echo "ERROR: item not found."
fi

Here, the output comes out incorrectly as

was successfully deleted

So $simpleName is blank for some reason. I can't figure out why it works in the first instance but not this instance.

Note: Both instances are within separate script files.

I'm aware that there are simpler ways to do things, however, I'm restricted to very very basic commands, I am not allowed to use sed, awk, grep, find, pretty much just what you see below.

2
  • Look at the two while loops and note that they are in fact not the same in terms of where you use the data read by the read utility.
    – Kusalananda
    Sep 19, 2021 at 17:00
  • I see what you're saying, but aren't the variables still within scope outside the while loop? Sep 19, 2021 at 17:03

1 Answer 1

0

read always assigns values to the variables, even if it doesn't see the expected delimiter and hence exits with a falsy status.

E.g.

$ (var=abcdef; 
   echo "      var=\"$var\"";
   read var;
   echo "ret=$? var=\"$var\"") < /dev/null
      var="abcdef"
ret=1 var=""

See also the idiom for processing a final incomplete line in a while read loop too: What does `while read -r line || [[ -n $line ]]` mean?

So, when you have this:

while read -r simpleName itemName; do
    read currentQuantity maximumQuantity
    read description
done < $FILE

a three-line input will first load all the variables, then try to read to simpleName and itemName again, trashing them. Or course this would also read the whole file, and e.g. a four-line input will leave all the variables empty.

I'm not sure what you want to do here, but perhaps something like this:

while    read -r simpleName itemName
      && read currentQuantity maximumQuantity
      && read description; do
    process one set of values ...
done < "$FILE"
4
  • Thank you, that put me on the right path. Knowing that it's trashing them at the end, basically means I need to do whatever I need to do with them, within the while loop, instead of afterwards. Sep 19, 2021 at 17:31
  • @PioneerRaptor, can the file actually even have more than those three lines? If not, you could just do { read && read && read; } < "$FILE" without the loop and use the variables directly. Or if know the file has blocks of three lines, you could use ... < <(tail -n3 "$FILE") to read the last three lines. (Which is not the same as looping over the triple read if the total number of lines isn't a multiple of three)
    – ilkkachu
    Sep 19, 2021 at 17:38
  • In this instance, all files are exactly the same format and same amount of lines. So thank you for that. bash is a lot different than C and Java, seems like there are so many more ways to do things. Sep 19, 2021 at 17:40
  • 1
    @PioneerRaptor yeah, well, nobody sane does actual data processing in sh or bash because it's a terrible language for doing that. Instead, they do the processing in C, java, awk, perl, python, or whatever else (anything but shell) and merely use a shell script as a wrapper around the code that does the work.
    – cas
    Sep 20, 2021 at 5:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .