1

I am working on a shell script to fetch data from DB and return results based on the input provided by user.

However I would like to limit the user to pass Maximum of a specific number (for eg. 10) comma separated values. Even if user has passed more than 10 values, my shell script should restrict the user and execute only 10 from the user provided list.

I'm able to fetch results for all user provided values, But not able to make out how to limit the same to a specific number.

My Shell Script

IDs=a1,b2,c3,d4,e5,f6,g7,h8,i9,j10,k11,l12,m13,n14
# Above are User provided sample alphanumeric values

for i in $(echo $IDs | sed "s/,/ /g")
do
  echo "Fetching results for $i by running sql against DB"
done

Expecting Results

I except shell script to fetch only first 10 comma separated values by ignore rest (In above eg. script need to pick values until from "a1" to "j10" and ignore rest) and execute the same against DB.

Any help would be greatly appreciated. Thanks in advance!

2
  • Note that you could just set counter=0 before starting your loop, put counter=$(( counter + 1 )) inside the loop, and then [ "$counter" -gt 10 ] && break or such in the loop to exit at the appropriate time. (Unlike the formal answer I provided, the above all works in baseline-POSIX shells). Commented Jul 18, 2019 at 13:46
  • Also, if you set IFS=, earlier in your script, for i in $IDs will split on commas (though it has other bugs unless you turn off globbing). Commented Jul 18, 2019 at 13:48

2 Answers 2

1

If you read your IDs into an array, you can use parameter expansion to take only the first 10 elements of that array, like so:

#!/usr/bin/env bash
#              ^^^^- NOT /bin/sh; arrays require a shell with ksh extensions.

IDs=a1,b2,c3,d4,e5,f6,g7,h8,i9,j10,k11,l12,m13,n14  # original input
IFS=, read -r -a id_arr <<<"$IDs"                   # transform into an array
max_count=10                                        # input w/ count to process

for i in "${id_arr[@]:0:max_count}"; do             # iterate only over that many
  echo "Fetching results for $i by running sql against DB"
done

In "${arrayname[@]:0:max_count}", the 0 is the starting position (we're starting from the beginning), and max_count is the number of items we're iterating over. See the bash-hackers' wiki page on parameter expansion.

Sign up to request clarification or add additional context in comments.

Comments

0

There are a lot of ways to slice-n-dice this one.

Here's one option that requires a small addition (cut) to the OPs current code to limit the number of items processed:

$ IDs=a1,b2,c3,d4,e5,f6,g7,h8,i9,j10,k11,l12,m13,n14

$ echo ${IDs} | cut -d"," -f1-10
a1,b2,c3,d4,e5,f6,g7,h8,i9,j10

$ for i in $(echo ${IDs} | cut -d"," -f1-10 | sed 's/,/ /g')
do
    echo "Fetching results for $i by running sql against DB"
done

Fetching results for a1 by running sql against DB
Fetching results for b2 by running sql against DB
Fetching results for c3 by running sql against DB
Fetching results for d4 by running sql against DB
Fetching results for e5 by running sql against DB
Fetching results for f6 by running sql against DB
Fetching results for g7 by running sql against DB
Fetching results for h8 by running sql against DB
Fetching results for i9 by running sql against DB
Fetching results for j10 by running sql against DB

3 Comments

for i in $(anything) is bad practice; see BashPitfalls #1. DontReadLinesWithFor is also closely related -- much of it applies to general string input, as opposed to line-oriented content alone.
Similarly, echo ${IDs} itself runs afoul of BashPitfalls #14.
yep, lots of issues with the OPs initial attempt ... and lots of (good and bad) ways to slice-n-dice the problem

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.