0

i was wondering if anyone could help me.

i am writing a program that looks in directories for a certain file. i have multiple directories inside a project folder some contain the file and others don't.

project 
    folderwithfile1
    folderwithfile2
    folderwithfile3
    folderwithoutfile

if this file exists in one of these folders, my program will sanitizes the file path to remove the filename result would be

home/newcoder/Desktop/project/folderwithfile1
home/newcoder/Desktop/project/folderwithfile2
home/newcoder/Desktop/project/folderwithfile3

now i would like to exclude/ignore certain folders from the search even if they contain the file. for example lets exclude folderwithfile1 and folderwithfile2.

my current code is

exclusionFilePaths=('/home/newcoder/Desktop/project/folderwithfile1' '/home/newcoder/Desktop/project/folderwithfile2')

for i in $(find ~+ -type f -name "fileWantToFind.php")
do
    sanitized=${i%/*}

for key in "${exclusionFilePaths[@]}";
do  
    if [ $sanitized == $key ]
    then 
       echo $sanitized
       #ignore and continue
    else
       echo veryLongCommand

    fi

  done
done

the result of my program is this

no
/home/newcoder/Desktop/project/folder1
/home/newcoder/Desktop/project/folder3
/home/newcoder/Desktop/project/folder3
/home/newcoder/Desktop/project/folder2
no

what am i doing wrong ? any help is appreciated, thank you.

markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • 1
    FYI, `for file in $(find ...)` [is itself an antipattern](https://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29). For the safe/correct way to use find, see the _Actions in Bulk_ section of [Using Find](https://mywiki.wooledge.org/UsingFind) – Charles Duffy Sep 01 '23 at 15:47
  • 1
    Also, `echo $sanitized` is buggy for the reasons given in [I just assigned a variable, but `echo $variable` shows something else!](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else), and `if [ $sanitized == $key ]` should be `if [ "$sanitized" = "$key" ]` -- but personally, I'd modify your `find` command so it never goes down those paths at all, which is something `-prune` is suited for. – Charles Duffy Sep 01 '23 at 15:49
  • It's also _much_ more efficient if you invert your array and make the paths the keys, not the values. If you have `declare -A valuesToExclude=( ["firstValue"]=1 ["secondValue"]=1 ["thirdValue"]=1 )` then it's a constant-time lookup with no iteration needed to check `[[ "${valuesToExclude[$valueToCheck]}" ]]` to see if `valueToCheck` is one of `firstValue`/`secondValue`/`thirdValue`. – Charles Duffy Sep 01 '23 at 15:51

2 Answers2

1

Example of using find -prune with some small cleanups.

#!/bin/bash
exclusionFilePaths=(
'/home/newcoder/Desktop/project/folderwithfile1' 
'/home/newcoder/Desktop/project/folderwithfile2'
)

# Build the required predicate for find to -prune undesired directories
exclusionArgs=( "(" "-path" "${exclusionFilePaths[0]}" )
for (( idx=1 ; idx < "${#exclusionFilePaths[@]}" ; idx++ )) ; do
  exclusionArgs+=( "-o" "-path" "${exclusionFilePaths[idx]}" )
done
exclusionArgs+=( ")" "-prune" )

# Use find -print0 to print all the remaining instances of fileWantToFind,
# then read and process them in a loop
while read -r -d '' line ; do
  sanitized="${line%/*}"
  veryLongCommand
done < <( find ~+ "${exclusionArgs[@]}" -o -name fileWantToFind.php -print0 )
# Important stuff:   ^^ predicate+prune ^^ OR   ^^ thing we want    ^  
#                                                                   |
#                                                         overrides implicit print
#                                                         when only action is -prune
tjm3772
  • 2,346
  • 2
  • 10
  • 1
    Include the `IFS=` to avoid truncating trailing/leading whitespace of the filepath, so the line should be something like`while IFS='' read -r -d '' line ; do`. But it seems like your code will work without it. – Aeronautix Sep 01 '23 at 20:16
0

You can exclude dirs in find

find ~+ -type f -name fileWantToFind.php -not \( -path /home/newcoder/Desktop/project/folderwithfile1/\* -o -path /home/newcoder/Desktop/project/folderwithfile2/\* \)
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134