1

I don't code in Bash daily. I'm trying to implement small functionality: user define an array of directories or files to omit in find command. Unfortunately I have a problem with expanding asterisk and other meta-characters by shell (* is expanded during concatenation). My code is:

excluded=( "subdirectory/a/*" 
        "subdirectory/b/*" 
        )

cnt=0
for i in "${excluded[@]}"; do
    directories="$directories ! -path \"./${excluded[$cnt]}\""
    cnt=$(($cnt+1))
done
echo "$directories"

for i in $(find . -type f -name "*.txt" $directories); do
    new_path=$(echo "$i"|sed "s/\.\//..\/up\//g")
    echo $new_path
done

Unfortunately, I still see excluded directories in results.

EDIT:

This is not duplicate of existing question. I don't ask you how to exclude directories in find. I have a problem with expanding meta-characters like "*" by passing variables to find command. E.g I have almost working solution below:

excluded=( "subdirectory/a/*" 
            "subdirectory/b/*"
            )

cnt=0
for i in "${excluded[@]}"; do
    directories="$directories ! -path ./${excluded[$cnt]}"
    cnt=$(($cnt+1))
done
echo "$directories"

for i in $(find . -type f -name "*.txt" $directories); do
    new_path=$(echo "$i"|sed "s/\.\//..\/up\//g")
    echo $new_path
done

It works, but problem is when e.g directory c contains more than one file. In such case, asterisk sign is replaced by full file paths. Consequently I have an error:

find: paths must precede expression: ./subdirectory/c/fgo.txt
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec]   [path...] [expression]

Why? Because asterisk sgin has been expanded to full file name:

! -path ./subdirectory/a/aaa.txt ! -path ./subdirectory/b/dfdji.txt ! -path ./subdirectory/c/asd.txt ./subdirectory/c/fgo.txt

My question is: how to avoid such situation?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Viper
  • 597
  • 1
  • 8
  • 24
  • possible duplicate of [exclude directory from find . command](http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command) – ffledgling Nov 21 '13 at 14:17
  • Not really. I asked about avoiding of asterisk expanding, not about find syntax - please see my EDIT – Viper Nov 21 '13 at 14:30

2 Answers2

1

You'll want to use the -prune switch in find.

Here's an example (I found this on stackoverflow itself)

find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -o -print

This omits, dir1, dir2, dir3.

Source: https://stackoverflow.com/a/4210072/1220089

Community
  • 1
  • 1
ffledgling
  • 11,502
  • 8
  • 47
  • 69
0

My initial thought is to use double quotes to prevent the expansion:

for i in $(find . -type f -name "*.txt" "$directories" | sed 's@\./@\.\./up/@g'); do

but this of course fails. You can accomplish the same effect with (untested):

pre='! -path'
excluded=( "$pre subdirectory/a/*" 
           "$pre subdirectory/b/*"
            )

for i in $(find . -type f -name "*.txt" "${excluded[@]}" | sed ...); do
William Pursell
  • 204,365
  • 48
  • 270
  • 300