LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-26-2017, 02:59 PM   #1
Jackoalltrades
LQ Newbie
 
Registered: Aug 2014
Distribution: Kubuntu
Posts: 7

Rep: Reputation: Disabled
Post Compare variable to array in Bash script


I am relatively inexperienced writing bash scripts and I'm trying to develop a script to take user input to create AWS CloudWatch metrics. Part of this script requires checking the input to confirm it is expected input that the rest of the script can use. I'm comparing the input to strings and figuring creating an array with all of the comparison values would be fastest, but I am having a difficult time formulating the if loop to determine if the variable provided by the user matches an element in the array.

Code:
echo "Please select the unit of measurement: Percent, Gigabytes, Count, etc. Make sure first letter is capitalized."
read UNIT
unitarray=(Seconds Microseconds Milliseconds Bytes Kilobytes Megabytes Gigabytes Terabytes Bits Kilobits Megabits Gigabits Terabits Percent Count Bytes/Second Kilobytes/Second Megabytes/Second Gigabytes/Second Terabytes/Second Bits/Second Kilobits/Second Megabits/Second Gigabits/Second Terabits/Second Count/Second)
if [[ ! $UNIT =~ $unitarray ]]; then
        echo "Please select a unit of measurement from the following list:"
        printf '%s\n' "${unitarray[@]}"
        exit 1
fi
This is the current iteration of the if loop. It works if the UNIT variable is "Seconds" but if I input any other string (like Microseconds or Bytes or Farts) it spits out the full list, meaning it didn't find it in the list, even using strings that do exist.

I've read a few dozen forum posts and read any number of instructional pieces on working with arrays, but I can't quite get it to work.

Thanks in advance for any assistance.
 
Old 04-26-2017, 04:17 PM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 21,611

Rep: Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169Reputation: 4169
Can't see the forest for the trees... Look at the output of $unitarray vs ${unitarray[@]} i.e.
Code:
echo $unitarray

echo ${unitarray[@]}
Which is why your string match only works for Seconds. The other gotcha is that a match will be true for any occurrence unless you include the field separator i.e a space". Since your a beginner at script writing try this:

Code:
if [[ ! " ${unitarray[@]} " =~ " ${UNIT} " ]]; then
This is only one of many ways to accomplish a string comparison.
 
2 members found this post helpful.
Old 04-26-2017, 05:23 PM   #3
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (current), FreeBSD, Win10, It varies
Posts: 9,952

Rep: Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148
if you notice in @michaelk post the use of { } curly brackets. it is a got a be to show the contents of inside an array. to get the everything in the array{@] is used
array.length for conditional in a loop is better then a hard coded number because that gives the number you want to end with if going through the entire array elements. Because what you stated is in error, This is the current iteration of the if loop.

"if [conditions]" are not loops.
Code:
for (( i = 0 ; i < "${#array[@]}" ; i++ ))
{
      echo "${array[i]}"
}
point is the use of the # and @ in an array. Along with { curly brackets }

this too can be taken care of so you do not have to worry about Caps in first letter words.
Code:
echo "Please select the unit of measurement: Percent, Gigabytes, Count, etc. Make sure first letter is capitalized."
Code:
if [ "${UNIT,,}" =~ "${unitarray[@],,}" ]; then
this lower cases everything.
example
Code:
"Solid" Variable

userx%slackwhere ⚡ ~ ⚡> var="TheEW Thoe"
userx%slackwhere ⚡ ~ ⚡> var2=${var,,}
userx%slackwhere ⚡ ~ ⚡> echo $var2
theew thoe

an Array
userx%slackwhere ⚡ ~ ⚡> var3=(t t t t R ewe Trush)
userx%slackwhere ⚡ ~ ⚡> var4=${var3[@],,}
userx%slackwhere ⚡ ~ ⚡> echo $var4
t t t t r ewe trush
userx%slackwhere ⚡ ~ ⚡>
example 2
Code:
userx%slackwhere ⚡ ~ ⚡> var="HeLLo YoU"
userx%slackwhere ⚡ ~ ⚡> var1=(HELLO you)
userx%slackwhere ⚡ ~ ⚡> [[ "${var,,}" =~ "${var1[@],,}" ]] && echo "hey got a match" 
hey got a match

userx%slackwhere ⚡ ~ ⚡> [[ "${var1[@],,}" =~ "${var,,}" ]] && echo "hey got a match"
hey got a match
as you can see on either end it still matches.

Now to nit pic your code. So you hopefully to pick up on a few things.
Hope you don't mind.
your code
Code:
echo "Please select the unit of measurement: Percent, Gigabytes, Count, etc. Make sure first letter is capitalized."
read UNIT
unitarray=(Seconds Microseconds Milliseconds Bytes Kilobytes Megabytes Gigabytes Terabytes Bits Kilobits Megabits Gigabits Terabits Percent Count Bytes/Second Kilobytes/Second Megabytes/Second Gigabytes/Second Terabytes/Second Bits/Second Kilobits/Second Megabits/Second Gigabits/Second Terabits/Second Count/Second)
if [[ ! $UNIT =~ $unitarray ]]; then
        echo "Please select a unit of measurement from the following list:"
        printf '%s\n' "${unitarray[@]}"
        exit 1
fi
can you justify the need for the use of an array when you can just make that a hard coded string?

because of this read UNIT that is the real variable yes? Whereas what you are using as an array is hard coded and will not change during run time, YES?
Code:
unitarray=(Seconds Microseconds Milliseconds Bytes Kilobytes Megabytes Gigabytes Terabytes Bits Kilobits Megabits Gigabits Terabits Percent Count Bytes/Second Kilobytes/Second Megabytes/Second Gigabytes/Second Terabytes/Second Bits/Second Kilobits/Second Megabits/Second Gigabits/Second Terabits/Second Count/Second)
which can be written just using " " quotes and the same conditional comparison used without an array.
Code:
unitarray="Seconds Microseconds Milliseconds Bytes Kilobytes Megabytes Gigabytes Terabytes Bits Kilobits Megabits Gigabits Terabits Percent Count Bytes/Second Kilobytes/Second Megabytes/Second Gigabytes/Second Terabytes/Second Bits/Second Kilobits/Second Megabits/Second Gigabits/Second Terabits/Second Count/Second"
too
Code:
read -p "Please select the unit of measurement: Percent, Gigabytes, Count, etc." UNIT
puts it on one line. less for the interpreter to evaluate. Faster run times. But you may not even need that whole string anymore. So I Shortened It In This Example.

one more thing, the use of string and substring when comparing strings. where to put which one?

Ok if you want to know this then pls read it.
test script
Code:
#!/bin/bash

substring="Terabits"

unitarray="Seconds Microseconds Milliseconds Bytes Kilobytes Megabytes Gigabytes \
Terabytes Bits Kilobits Megabits Gigabits Terabits Percent Count Bytes/Second Kilobytes \
/Second Megabytes/Second Gigabytes/Second Terabytes/Second Bits/Second Kilobits/Second Megabits/Second \
 Gigabits/Second Terabits/Second Count/Second"

echo "$unitarray"

if [[ ${unitarray,,} =~ ${substring,,}  ]] ; then
	echo "got a match"
else
	echo "nO match"
fi
notice the use of the \ to split the line so you can move it down onto another line and still have it read as one complete line. Along with no use of an array.

results
Code:
userx%slackwhere ⚡ scripts ⚡> ./LongString
Seconds Microseconds Milliseconds Bytes Kilobytes Megabytes Gigabytes Terabytes Bits Kilobits Megabits Gigabits Terabits Percent Count Bytes/Second Kilobytes /Second Megabytes/Second Gigabytes/Second Terabytes/Second Bits/Second Kilobits/Second Megabits/Second  Gigabits/Second Terabits/Second Count/Second
got a match

Last edited by BW-userx; 04-26-2017 at 06:18 PM.
 
1 members found this post helpful.
Old 05-08-2017, 02:50 PM   #4
Jackoalltrades
LQ Newbie
 
Registered: Aug 2014
Distribution: Kubuntu
Posts: 7

Original Poster
Rep: Reputation: Disabled
Both of these responses were very helpful in understanding some of the differences between using strings and arrays.

Thank you both very much!
 
Old 05-10-2017, 08:55 PM   #5
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 7.7 (?), Centos 8.1
Posts: 17,873

Rep: Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600Reputation: 2600
If you're going to mess with arrays, I highly recommend this http://wiki.bash-hackers.org/syntax/arrays
 
  


Reply

Tags
array, bash, compare, loop, script


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to use a variable to index an array in Bash shell script? anotheremily Programming 3 06-22-2012 09:46 PM
[SOLVED] reference bash array values, using a variable with a value of the array name gusthecat Programming 5 03-07-2012 03:41 PM
create a global associative array variable inside a function of a bash script konsolebox Programming 3 07-14-2009 06:08 AM
passing array and variable to function in bash script ajaypitroda Programming 2 07-07-2009 11:10 PM
How do you compare variable in bash programming? chynna_v Programming 6 09-08-2004 02:17 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 09:02 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration