Find Command Search Only Non Hidden Directories

How do I exclude a directory when using `find`?

Use the -prune primary. For example, if you want to exclude ./misc:

find . -path ./misc -prune -o -name '*.txt' -print

To exclude multiple directories, OR them between parentheses.

find . -type d \( -path ./dir1 -o -path ./dir2 -o -path ./dir3 \) -prune -o -name '*.txt' -print

And, to exclude directories with a specific name at any level, use the -name primary instead of -path.

find . -type d -name node_modules -prune -o -name '*.json' -print

How to ignore `.*` folders and files when using `find` command?

I believe there are several ways to do this, for example:

find . \( ! -regex '.*/\..*' \) -type f -name "something"

The first example won't show you any hidden file or directory.

find . \( ! -regex '.*/\..*/..*' \) -type f -name "something"

The second just discards the hidden directories, showing the hidden files into normal directories.

It's the regular expression option of find.

Here is a complete explanation: find command search only non hidden directories

EDIT 1:

find . -type f -not -name ".*"

Get all directories (hidden and non-hidden) in bash

Simple find should do it:

find /some/path -mindepth 1 -maxdepth 1 -type d

-maxdepth 1 ensures you don't descend into subdirectories. However, if that's what you want, you can just remove it.

-mindepth 1 ensures find does not include the directory itself.

Find all directories that contain only hidden files and/or hidden directories

Parsing find's output is not a good idea; -exec exists, and sh can do the filtering without breaking anything.

find . -type d -exec sh -c '
for d; do
for f in "$d"/*; do
test -e "$f" &&
continue 2
done
for f in "$d"/.[!.]* "$d"/..?*; do
if test -e "$f"; then
printf %s\\n "$d"
break
fi
done
done' sh {} +

You can adjust the depth using whatever extension your find provides for it.

Find Command Exclude Hidden files when using empty flag

The -empty predicate is rather simple, it's true for a directory if it has any entries other than . or ...

Kind of an ugly solution, but you can use -exec to run another find in each directory which will implement your criteria for deciding what directories you want to include.

Below:

  • the outer find will execute sh -c for each directory in /starting/point
  • sh will execute another find with different criteria.
  • the inner find will print the first match and then quit
  • read will consume the output (if any) of the inner find. read will have an exit status of 0 only if the inner find printed at least one line, non-zero otherwise
  • if there was no output from the inner find, the outer find's -exec predicate will evaluate to false
  • since -exec is followed by -o, the following -print action will be executed only for those directories which do not match the inner find's criteria
find /starting/point \
-type d \( \
-exec sh -c \
'find "$1" -mindepth 1 -maxdepth 1 ! -name ".*" -print -quit | read' \
sh {} \; \
-o -print \
\)

Ignore/prune hidden directories with GNU find command

The latter command prunes everything because it prunes . - try these to see the difference:

$ ls -lad .*
.
..
.dotdir
$ ls -lad .?*
..
.dotdir

You see that in the second one, . isn't included because it is only one character long. The glob ".?*" includes only filenames that are at least two characters long (dot, plus any single character, non-optionally, plus any sequence of zero or more characters).

By the way, find is not a Bash command.

Why does find . -not -name .* not exclude hidden files?

The thing is -not -name ".*" does match all files and directories that start with anything but "." - but it doesn't prune them from the search, so you'll get matches from inside hidden directories. To prune paths use -prune, i.e.:

find $PWD -name ".*" -prune -o -print

(I use $PWD because otherwise the start of the search "." would also be pruned and there would be no output)

How to search hidden directories/files with path=.,** and :find?

The built-in routine used for searching files uses a "depth-first search" algorithm which makes it quite inefficient in many scenarios. set path=.,** may thus be a bit excessive as it will force Vim to look into every subdirectory before switching to the next directory. It may work in some cases (as emphasized in my answer you linked to) but you should know that 'path' is intended as a list of specific directories and having ** in there kind of defeats its point. The "right" way to make :find go through hidden directories is to add them to 'path':

set path+=.some_dir
set path+=.some_other_dir

While it would certainly be an improvement over the current situation, replacing the current algorithm with a "better" one (say
iterative deepening depth-first search) can only be done in Vim's C source as Vim doesn't expose a 'filesearchprg' option or similar, unfortunately.



Related Topics



Leave a reply



Submit