flybywire
flybywire

Reputation: 273952

Can 'find' or any other tool search for files breadth-first?

Sometimes I know a file is not so deep away, but a very dense sub-directory does not allow me to find the files I want easily.

Can find (or any other tool) look for files using breadth-first search?

Upvotes: 36

Views: 8428

Answers (6)

This bash solution is inspired by the one by Jethro Yu, and improves it in two ways:

  1. It calls find once for each directory, not twice.
  2. It uses the builtin readarray instead of echo | xargs ..., and as a side effect of this, correctly handles paths containing \n.

find-bfs() {
  local queue=("${1:-.}")
  shift

  while [[ ${#queue[@]} -gt 0 ]]; do
    echo "$queue"
    readarray -t queue < <(find "${queue[@]}" -mindepth 1 -maxdepth 1 $*)
  done
}

Upvotes: 1

Duncan Grant
Duncan Grant

Reputation: 1

find . | awk '{FS = "/" ; print "", NF, $F}' | sort -n  | awk '{print $2}' | xargs grep -d skip "search term"

It uses find to list all the files. The first awk command counts all the '/' characters. It sorts on the count and then drops the count column. Finally it uses xargs to grep the sorted list of files.

It is really ugly.

Upvotes: -1

Jethro Yu
Jethro Yu

Reputation: 599

A breadth-first find using variable as its queue.

Create bfs.sh

#!/bin/bash

queue="$1"
shift

while [ -n "$queue" ]
do
    echo "$queue" | xargs -I'{}' find {} -mindepth 1 -maxdepth 1 $*
    queue=`echo "$queue" | xargs -I'{}' find {} -mindepth 1 -maxdepth 1 -type d`
done

Make it executable:

$ chmod u+x ./bfs.sh

Then you can do a breadth-first find by:

$ ./bfs.sh /path/to/somewhere -name foobar

Upvotes: 7

ephemient
ephemient

Reputation: 204956

Horrible hack, won't work with -0 or any actions other than -print, inefficient, etc. etc…

#!/bin/bash
i=0
while results=$(find -mindepth $i -maxdepth $i "$@") && [[ -n $results ]]; do
    echo "$results"
    ((i++))
done

Basically this just runs

find -mindepth 0 -maxdepth 0
find -mindepth 1 -maxdepth 1
find -mindepth 2 -maxdepth 2
…………………………………………………………………………

until find returns non-zero status or prints nothing.

Upvotes: 12

nik
nik

Reputation: 13468

Use find with the --maxdepth option.

That is at the Directories section in your reference page; might find other options more suitable depending on your needs.

To achieve exact breadth first searching, you will need to loop with mixed --mindepth and --maxdepth options. But, I don't think it is necessary to be that exact, a depth limited search will usually suffice.

Upvotes: 5

unwind
unwind

Reputation: 400029

Yes, sort of.

You can use the -depth option to make it process a directory's contents before the directory itself. You can also use the -maxdepth option to limit how many directories down it will drill.

Upvotes: 18

Related Questions