In Bash, with shopt -s extglob
, and also zsh with KSH_GLOB
enabled:
for f in *.@(bw|txt)
Note that in bash, if there are no matches, the loop will run with $f
set to the literal string *.@(bw|txt)
. To avoid this, in bash:
shopt -s nullglob
for f in *.@(bw|txt)
In zsh, by default, you'll get an error if there are no matches. To avoid this, add the N
glob qualifier.
for f in *.@(bw|txt)(N)
In zsh, there's a simpler solution that works with default options, again with (N)
to do nothing if there are no matches:
for f in *.(bw|txt)(N)
All of those will order all the entries alphabetically, with files with both extensions intermingled (that is, duplicate names that differ only in the extensions will (likely¹) be consecutive). You can list as many pipe-separated pattern entries within the parentheses as required, and they can include further globs (e.g. (zip|tar.?z)
).
¹ foo.bw
foot.bw
foot.txt
foo.txt
however would sort in that order in locales where .
is ignored in first instance in the collation algorithm as is common these days (as footb
or foott
come before footx
and after foobw
).
for f in *bw *txt;do echo $f;done
is not what you want?printf '%s\n' *bw *txt
, unless you rely on the fact that the (bash
) shell would perform splitting and globbing of your unquoted variable.