There are many ways to deal with it.
There are, rightly, misgivings about parsing the output of ls
. How justified those are depends on whether you have to deal with all possible file names (ones containing spaces and newlines are particularly problematic), or whether you have normal file names that use just the portable filename character set (which, according to POSIX, are the (Latin) alphabet, the digits, plus .
, -
, and _
).
Assuming that you only have to deal with portable filenames, then you could get the effect you wanted with:
for i in $EXCLUDE
do
echo $i
f="$f | grep -v $i"
done
for d in `eval ls $AWSTATSCONF/awstats*conf $f`
do
echo $d
done
Using eval
like that forces the shell to treat the pipes in the string $f
as pipes in the shell. Beware: eval
is a powerful and therefore dangerous tool.
The chosen mechanism of running 20 greps in sequence if there are 20 terms to exclude uses a lot of processes. It probably won't be too serious for demonstration purposes, but if you're dealing with production work and thousands of files...not so good.
You'd probably want to look at building an egrep
(or grep -E
) command:
f="antidisestablishmentarianism"
for i in $EXCLUDE
do
f="$f|$i"
done
ls $AWSTATSCONF/awstats*conf |
egrep -v "$f" |
while read d
do echo $d
done
I assume you don't have any stats files with names containing 'antidisestablishmentarianism' lurking around (yes, it's a real word; it is mostly used here as a joke, though).
The while read
formulation is another way of writing the for
loop. Be wary of subprocesses not being able to affect the parent shell's variables. That is, the while
loop is processed by a sub-shell, not the main shell, so if you are relying on the loop to set variables in the main shell, it won't work — and you can/should go back to the for
loop. However, you don't need eval
again:
for d in $(ls $AWSTATSCONF/awstat*conf | egrep -v "$f")
do
echo $d
done
Using $(...)
instead of back-quotes is generally a good idea.