Reputation: 58
I want to send a list of extensions as a parameter. So I wrote a small helper function that parses a string of extensions and formats it in a way that "find" utility expects:
exts="txt log";
track=0;
function ext_parse()
{
for i in $exts; do
if [[ $track -eq 0 ]]
then
varstr="-iname \"*.$i\"";
track=1;
else
varstr="$varstr -o -iname \"*.$i\" ";
fi
done
echo "$varstr";
}
So it returns:
-iname "*.txt" -o -iname "*.log"
If I put this into "find" directly it works well:
find . -type f \( -iname "*.txt" -o -iname "*.log" \) -print
But any attempt to substitute this string with the function above that I've tried fails.
Is there any way to obtain that behavior or it is impossible by design?
Upvotes: 1
Views: 40
Reputation: 46853
I would argue it's cleaner, safer and easier to use arrays:
ext_parse() {
local i
varstr=()
for i; do
((${#varstr[@]}!=0)) && varstr+=( -o )
varstr+=( -iname "*.$i" )
done
}
To use this function, you would first call it with appropriate arguments, e.g., ext_parse txt log
; this will set the array varstr
; and then you can use it as:
find -type f \( "${varstr[@]}" \)
So your workflow looks like this:
$ ext_parse txt log
$ find -type f \( "${varstr[@]}" \)
RE: your comment: to clarify your worry about find
being run once per element in array (which is wrong!), do the following test: save the following script as banana
:
#!/bin/bash
for ((i=1;i<=$#;++i)); do
printf 'Argument %d: %s\n' "$i" "${!i}"
done
Then chmod +x banana
, and try it:
$ ext_parse txt log
$ ./banana -type f \( "${varstr[@]}" \)
Argument 1: -type
Argument 2: f
Argument 3: (
Argument 4: -iname
Argument 5: *.txt
Argument 6: -o
Argument 7: -iname
Argument 8: *.log
Argument 9: )
So you can see that banana
is executed once only, with all the arguments given above: exactly what you want!
Upvotes: 1