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 executesh -c
for each directory in/starting/point
sh
will execute anotherfind
with different criteria.- the inner
find
will print the first match and then quit read
will consume the output (if any) of the innerfind
.read
will have an exit status of 0 only if the innerfind
printed at least one line, non-zero otherwise- if there was no output from the inner
find
, the outerfind
'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 innerfind
'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
Aosp Build Error: Unrecognized Module Type "Hidl_Package_Root"
Git Is Not Ignoring File Permission Changes
How to Remove Space/Tab from Command Output
How to Source a Simple Bash Script
Keep Ssh Sessions Running After Disconnection
Grep If The Next X Lines Doesn't Contain a Specific String
Command Execution with Nohup in Background
Linux Select() and Fifo Ordering of Multiple Sockets
Bash - While Read Line from File Print First and Second Column
How to Use 'Catdoc' to Display Dock File Encoded in Utf-8
Level Triggered Interrupt Handling and Nested Interrupts
Phony Targets for Parallel Execution of Make
How to Make Sudo Save The Password
In Shellscript Assign Variable Based on Curl Output
Testing - Intentionally Corrupt a .Z File Using 'Dd'
Maximum Number of Threads Allowed to Run