I have a script that’s taking some comma separated IDs as an argument, and I want to check if they are valid inputs, i.e. they should be a subset of IDs present in a postgres table.
I have this one solution,
ARGUMENTS="value1,value2,value3"
PSQL_COMMAND="SELECT id FROM users;"
OUTPUT=$(psql -U username -d database_name -c "$PSQL_COMMAND" -t)
IFS=',' read -ra VALUES <<< "$OUTPUT"
for value in "${VALUES[@]}"
do
if echo "$ARGUMENTS" | grep -q -E "(^|,)$value(,|$)"; then
echo "$value is a subset of $ARGUMENTS"
else
echo "$value is not a subset of $ARGUMENTS"
fi
done
But I was wondering if there’s a better way to do this.
Would appreciate all your answers.
3
Answers
Suggest you use variable names that are more meaningful to the process that is being coded. It provides a form of embedded documentation which makes it easier for code maintenance. You might also want to isolate the two groupings of test results, positive/negative, into separate streams, depending on how you want to use those results for additional downstream processing. Otherwise, you logic is good, crisp and clean.
My test (and revised) version of your script:
You may be able to avoid the call to
grep
inside your loop by using bash constructs. Here are three options:case
statement instead ofif
:there is a more efficient way as long as you can guarantee a dedicated separation character (here I used the percentage sign) to never ever occur in the values. The code looks a bit cryptic, but it does NOT have a loop.
The monstrous SED at the end is just for nice display and you maybe just want to filter out the matching >>OR<< the not matching names.
This code will break as soon as your value list exceeds the line size limit of SED.
e.g. a statement like
grep -E "$ARGUMENTS" <<< "$OUTPUT"
when issued from command line in interactive shell with ESC sequence support would highlight all found values. In script call, there is no colored output of "grep", so it will just find the only existing data line … no use for that of cause. The interactive call of grep is just mentioned to show some of your options.