2

I have a text file I am trying to read into an Array using Bash. Here are the contents of text file:

Vol12
Vol0
Vol2
Vol21

I want to extract the number from the above string and present it to the user to select the number to enter choice such:

12 - Vol12
0  - Vol0
2  - Vol2
21 - Vol21

User would enter 12 to select Vol12 or 2 to select Vol2 and use the selection to do further action.

I have been searching how to do this but here is what I have so far:

Vol="/Users/alex/Downloads/file.txt"

options=($(tail -n+1 $Vol | awk '{print $1}' | sort | uniq) All Quit)

for (( i = 0; i < ${#options[@]}; i++ )); do
    echo "$i - ${options[i]}"
done

echo -e "Enter number corresponding to the Volume snapshot you want to restore: \n"
read vol

}

Following output is what I am getting with above code:

OPTIONS MENU
0 - Vol12
1 - Vol0
2 - Vol2
3 - Vol21
4 - All
5 - Quit
Enter number corresponding to the Volume snapshot you want to restore: 

How can I get the output to show like following and able to select 12 or 0 ?

12 - Vol12
0  - Vol0
2  - Vol2
21 - Vol21

Please help

1 Answer 1

2

You can use associative arrays:

#!/bin/bash
Vol="/Users/alex/Downloads/file.txt"
declare -a arr

#Loop reads each line of the file
while IFS= read -r line; do
    n=${line##*[!0-9]}       #Gets the number at the end of this line
    arr[$n]=$line            #Uses it as the key to the array, the content being the whole line
    echo "$n - $line"
done < "$Vol"

read -p "Select one from above. " vol
echo "You selected ${arr[vol]}."

For example (I saved it as sh.sh):

$ ./sh.sh
12 - Vol12
0 - Vol0
2 - Vol2
21 - Vol21
Select one from above. 2
You selected Vol2.
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks. Would it be easier to extract the number at the end of Vol##? So Vol has 3 characters,(Vol##). How can I extract the number after Vol?
@NetSystemAdmin You're welcome. I'm not sure I understand your question. It will work with Vol1, Vol11, Vol111, ...
@NetSystemAdmin if this works for you then you need to accept this and up vote...
I went a different route. This works: for (( i = 0; i < ${#options[@]}; i++ )); do num=${options[i]#Vol} echo "$num - ${options[i]}" done
It is possible to fill the array in one go with: declare -a arr="($(<"$Vol" xargs -n 1 -d '\n' bash -c 'printf "[%d]=%q\n" "${0##*[^[:digit:]]}" "$0"'))"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.