0

I have a bunch of files with digits in their names. Each file number belongs to a "group" or range of numbers. I'd like to match the file number within the group it is in and then export that as a variable. I'm not sure how to do this, but I assume it would be something similar to:

Array:
(A, 1, 20)
(B, 21, 34)
(C, 35, 52)
(D, 53, 68)

Where the first column is the group name, the second column is the first digit in the range and the last column is the last digit in the range. Then, I could apply something like:

if [ $num -ge "COLUMN2" ] && [ $num -le "COLUMN3" ]; then
    groupname=COLUMN1
fi

I'm new to coding and just began learning the bash shell, so I would really prefer if you only gave me ways to this in bash. Also, I know that the second column seems unnecessary when you could just do while [ $num -ge "COLUMN3" ], but I need the first column later in the script.

3
  • Can you give an example of the input and the hoped-for output? Commented Dec 4, 2011 at 17:22
  • Are there gaps possible between the numbers of two groups? The numbers above go fro 1 to 68 without a gap. Commented Dec 4, 2011 at 17:44
  • Input would be any number and output would be the group name that corresponds to that number. So if I input 37, it will output "C". There are no gaps because the files were created one after another, with the "total number" appended to it. Numbers greater than the last value, however, need to output an error message reminding me to add groups that go up to that number. Commented Dec 4, 2011 at 19:39

2 Answers 2

2

bash doesn't really do multidimensional arrays, but for this purpose a series of single-dimension arrays should do fine:

group_names=("A" "B" "C" "D")
group_min=(1 21 35 53)
group_max=(20 34 52 68)

groupname=
for (( i=0; i < ${#group_names[@]}; i++ )); do
    if [ $num -ge ${group_min[i]} ] && [ $num -le ${group_max[i]} ]; then
        groupname="${group_names[i]}"
        break
    fi
done
if [ -z "$groupname" ]; then
    echo "Oops, no matching group found!"
fi
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! I had thought about something similar, but wanted to know if there was a "cleaner" or correct method. Good to know that bash can't do "multidimensional arrays" (on that note, does multidimensional extend to 3 dimensions, or just 1 and 2? That'd be awesome, if not mind-melding)
Why is it necessary to do for (( i=0; i < ${#group_names[@]}; i++ ))? Wouldn't for x in ${group_names[@]} be enough? I'm new to coding and would like to understand the advantages and differences between the two.
1: different languages have different array capabilities, but generally arrays can have as many dimensions as you want (231 dimensions? No problem!). 2: for x in "${group_names[@]}" (note the double-quotes to avoid trouble with e.g. spaces in the group names) would work to iterate through the group_names array, but gives you no way to refer to the corresponding entries in group_min and group_max. Instead, you need to iterate over the array index, and use that to access the values in all three arrays.
0

This might work for you too:

$ number=51 group=
$ array=("A 1 20" "B 21 34" "C 35 52" "D 53 68")
$ for element in "${array[@]}"
> do read key min max <<<"$element"
> (( number >= min && number <= max )) && group=$key && break
> done
$ [[ $group ]] && echo "number=$number group=$group" || echo "number=$number no match"
$ number=51 group=C

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.