I am trying to use find (or a similar tool, I also really like fd)

  • to locate directories matching the query

  • only those directories which are the deepest match

  • the target directories are not all the same depth, so -maxdepth or -mindepth can't do it

  • it would be the opposite of -prune

Given the below directory tree, looking for directories with "red" in the name, the ones with Yes should be the matches:

$ tree
.
├── blue                = n
├── green               = n
│   ├── red-apple       = Yes
│   └── red-book        = n
│       └── red-pen     = Yes
├── red                 = n
│   └── red-strawberry  = Yes
│   └── 
└── yellow              = n
    └── basket          = n
        ├── flag        = n
        │   └── red     = Yes
        └── painted-red = Yes
            └── wagon   = n

So "red-book" does not match because it contains a subsequent match ("red-pen"). But it's OK to have a deeper non-matching directory (like "painted-red").

This is my basic command which finds 2 unwanted items:

$ find . -type d -name "*red*"
./green/red-apple
./green/red-book
./green/red-book/red-pen   # wrong
./yellow/basket/flag/red
./yellow/basket/red
./red                      # wrong
./red/red-strawberry

all 2 comments

sorted by: hot top controversial new old
[–] 2 points 1 month ago* (last edited 1 month ago)

Did you ever figure this out? I screwed around for a couple of minutes, and the closest I could get was:

$  find ./ -type d -empty | grep red
./green/red-apple
./green/red-book/red-pen
./red/red-strawberry
./yellow/basket/flag/red
./yellow/basket/painted-red/wagon

I'm not really sure if that's what you were trying to do. I'm pretty sure my try is far from robust.

  • source
  • [–] 1 point 2 weeks ago

    Hello! First of all, I wrote this myself without AI (but with a stackover post here for the word counter (wc) part and here for the -exec of find part).

    How it works

    We select a directory called A. If A has a sub-directory at somepoint with the matching string "red" in it, we then ignore it. Otherwise, it is the deepest directory with "red" in its name. That makes sense. So, how do we do this?

    First, I wrote a find.sh script

    if [[ $(find "$1" -mindepth 1 -type d -name '*red*' | wc -c) -eq 0 ]]; then
      echo "$1"
    fi
    

    It will output the name of the directory if it is the deepest match, or nothing if not. Then I do

    find . -type d -name '*red*' -exec bash find.sh {} \;

    Finally

    find . -type d -name '*red*' -exec $SHELL -c 'if [[ $(find "$1" -mindepth 1 -type d -name "*red*" | wc -c) -eq 0 ]]; then echo $1; fi' sh {} \;

    Hope this helps 👍

  • source