views:

40

answers:

2

I wrote this piece of code to scan a directory for files newer than a reference file while excluding specific subdirectories.

#!/bin/bash

dateMarker="date.marker"
fileDate=$(date +%Y%m%d)
excludedDirs=('./foo/bar' './foo/baz' './bar/baz')
excludedDirsNum=${#excludedDirs[@]}

for (( i=0; i < $excludedDirsNum; i++)); do
    myExcludes=${myExcludes}" ! -wholename '"${excludedDirs[${i}]}"*'"
done

find ./*/ -type f -newer $dateMarker $myExcludes > ${fileDate}.changed.files

However the excludes are just being ignored. When I "echo $myExcludes" it looks just fine and furthermore the script behaves just as intended if I replace "$myExcludes" in the last line with the output of the echo command. I guess it's some kind of quoting/escaping error, but I haven't been able to eliminate it.

A: 

you need the myExcludes to evaluate to something like this:

\( -name foo/bar -o -name foo/baz -o -name bar/baz \)

ennuikiller
A: 

Seems to be a quoting problem, try using arrays:

#!/bin/bash

dateMarker=date.marker
fileDate=$(date +%Y%m%d)
excludedDirs=('./foo/bar' './foo/baz' './bar/baz')
args=(find ./*/ -type f -newer "$dateMarker")
for dir in "${excludedDirs[@]}"
do
    args+=('!' -wholename "$dir")
done
"${args[@]}" > "$fileDate.changed.files"

Maybe you also need -prune:

args=(find ./*/)
for dir in "${excludedDirs[@]}"
do
    args+=('(' -wholename "$dir" -prune ')' -o)
done
args+=('(' -type f -newer "$dateMarker" -print ')')
Philipp
Thanks a lot for your answer. It works like a charm without the need of -prune.
raphinesse