Gerald Loo
Gerald Loo

Reputation: 25

How to use mapfile and several arrays?

In my last ask, I learned how to use mapfile to get a bit of text into an array. But when trying to loop it through the file I found it only got the first part of the text file and not any other lines. I think I might be missing a way to check/read through several arrays in the file.

patron.txt =

123456:Gerald:012-9999999:[email protected]
999999:Tom:010-8888888:[email protected]

Current Code:

#!/bin/bash
echo "Search Patron Details"
echo -n "Enter Patron ID: "
read id1
mapfile -d: -t array < <(grep -i "$id1" patron.txt)
echo "Fullname (auto display): ${array[1]}"
echo "Contact Number (auto display): ${array[2]}"
echo "Email Adddress (auto display): ${array[3]}"
echo -n "Would you like to continue searching for patrons? (y)es or (q)uit: "
read option
case $option in
 y|Y) bash show_details;;
 q|Q) bash main_menu;;
 *) echo "Invalid entry";;
esac

Intended Result:

Search Patron Details
Enter Patron ID: 999999
Fullname (auto display): Tom
Contact Number (auto display): 010-8888888
Email Adddress (auto display): [email protected]
999999
Would you like to continue searching for patrons? (y)es or (q)uit: y

Search Patron Details
Enter Patron ID: 123456
Fullname (auto display): Gerald
Contact Number (auto display): 012-9999999
Email Adddress (auto display): [email protected]

Actual Result:

Search Patron Details
Enter Patron ID: 999999
Fullname (auto display): Gerald
Contact Number (auto display): 012-9999999
Email Adddress (auto display): [email protected]
999999
Would you like to continue searching for patrons? (y)es or (q)uit: y
Search Patron Details
Enter Patron ID: 123456
Fullname (auto display): Gerald
Contact Number (auto display): 012-9999999
Email Adddress (auto display): [email protected]

This is from lessons of classrooms, we have limited shell knowledge.

Upvotes: 0

Views: 481

Answers (3)

Not a perfect answer, but substitute your grep

grep -i "$id1" patron.txt

with this:

grep -i "^$id:" patron.txt

Thanks to the "^", the searched term must reside at the beginning of the line.

Thanks to the trailing ":", the searched term must end with ":" which is also the field separator. In other word, this grep searches the records having $id as first field.

Note also that, this way, you can not search anymore for partial matches. To do that, one should first isolate the first field and then perform a search on it (more complicated).

Upvotes: 1

Ivan
Ivan

Reputation: 7317

Um, why so complicated? Just use awk:

$ awk -v id=123456 -F: '$1 == id{printf "Name: %s\nNumber: %s\nEmail: %s\n", $2,$3,$4}' patron.txt 
Name: Gerald
Number: 012-9999999
Email: [email protected]

Upvotes: 1

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185730

What I would do, re-using the maximum of your previous code:

#!/bin/bash
echo "Search Patron Details"
echo -n "Enter Patron ID: "
read id1
array=( $(awk -F':' -v OFS=" " -v id=$id1 '$1==id{$1=$1}1' < patron.txt) )
cat<<EOF
Fullname (auto display): ${array[2]}
Contact Number (auto display): ${array[3]}
Email Adddress (auto display): ${array[4]}
EOF

Or using only bash:

#!/bin/bash
echo "Search Patron Details"
echo -n "Enter Patron ID: "
read id1
mapfile lines < file
for line in "${lines[@]}"; do
    IFS=: read id name phone email <<< "$line"
    if ((id==id1)); then
        cat<<EOF
        Fullname (auto display): $name
        Contact Number (auto display): $phone
        Email Adddress (auto display): $email
EOF
    fi
done < file

Upvotes: 0

Related Questions