Search code examples
bashmap-files

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:asdf@gmail.com
999999:Tom:010-8888888:zxcv@gmail.com

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): zxcv@gmail.com
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): asdf@gmail.com

Actual Result:

Search Patron Details
Enter Patron ID: 999999
Fullname (auto display): Gerald
Contact Number (auto display): 012-9999999
Email Adddress (auto display): asdf@gmail.com
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): asdf@gmail.com

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


Solution

  • 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).