Comments on In a bash shell script, how to filter the command line argument list to unique entries only, for processing each?
Parent
In a bash shell script, how to filter the command line argument list to unique entries only, for processing each?
I have a handful of shell scripts that accept any number of command line arguments, then do some relatively expensive processing based on each command line argument in turn. The general format for these goes along the lines of
#!/bin/bash
# preliminary set-up goes here
# main loop:
while test -n "$1"
do
do_expensive_processing_for "$1"
shift
done
# tear-down goes here
This works mostly well. However, it has the downside that if I for some reason pass the same argument twice during an invocation, that argument gets processed twice. Since the processing is expensive, I want to avoid that.
How can I ensure that each command line argument is processed only once during a single invocation of the script, while still allowing arbitrary command line argument contents (or at least not restricting them more than the above type of bash script already would)?
I'm happy with any one instance being the one that gets processed; the order of processing is not important.
To the extent that it matters, I'm using GNU bash 5.1.
Post
The following users marked this post as Works for me:
User | Comment | Date |
---|---|---|
Canina | (no comment) | Oct 15, 2021 at 09:22 |
The solution is to use an associative array to store what you've already seen:
#!/bin/bash
unset seen
declare -A seen
for arg in "$@"
do
if [[ -z "${seen[$arg]}" ]]
then
echo "Doing something omplicated with $arg"
seen["$arg"]=1
fi
done
The unset seen
is just in case the caller had an exported variable named seen
. The declare -A seen
tells bash to treat seen
as an associative array, that is, it takes arbitrary strings as index.
The loop then tests for each argument whether it has not yet been seen (in which case "${seen[arg]}"
is empty). If so, it processes it and then marks it as seen by storing something in seen["$arg"]
(what it stores doesn't really matter as long as it is not empty; if you want, you can store additional information about the argument here, e.g. the result of processing this argument).
0 comment threads