- find Command Logical AND, OR and NOT Examples
- Find Command – Logical AND
- Logical OR Along with Find Command
- Logical NOT Examples
- Conclusion
- Related Articles
- Команда find Linux
- Поиск
- -name: Поиск по имени
- Поиск по расширению
- -not: обратное условие
- Несколько условий вместе
- -o: Логическое или
- Найти и скопировать
- Поиск по типу
- Уровни вложенности
- Поиск по размеру файла
- Поиск по началу имени файла
- Поиск по части имени файла
- -perm: поиск по правам доступа
- -path: поиск путей
- -prune: ограничить глубину
- Исключить директорию из поиска
- How to ignore certain filenames using «find»?
- 5 Answers 5
find Command Logical AND, OR and NOT Examples
The Linux find command is a very versatile and powerful command and is frequently used while working on the command line. it is used to search for files and directories that match a particular criterion or more than one criteria. Logical AND, OR and NOT Examples.
We could search for files by permissions, users, file type, date, size, creation/modification time and other possible requirements. By using the – exec options with the find command, other UNIX commands can be executed on resulting matches found by the find command.
In this article, however, we would not be presenting the full feature set that find has to offer but instead, focus on an interesting subset of its features. We will show you how we could perform logical AND, OR and NOT operations on our search criteria while working with the find command. So, for this article, we assume that you have a basic understanding of how the find command works. If not refer this previous article to learn
Find Command – Logical AND
Included this mainly for the sake of completeness actually. This is because every search we perform using the find command mentioning more than one search criteria is an implicit logical AND operation.
Consider the below example
$ find . -name "*.bash" -mtime +180 -size +2K -exec ls -l <> \;
In the above command, we are telling find to search for files/directories with the string .bash in their name, they should be older than 180 days and should have a size greater than 2KB.
Finally, we execute the ls -l command on the results produced from the find command by using the -exec option.
So find would search for and display only those files matching all the three conditions thereby performing a logical AND operation.
Logical OR Along with Find Command
Let’s consider a scenario wherein we need to modify the example we used previously and obtain files with the strings .bash as well as .txt. To fulfill this requirement use the -o option with the find command to indicate a logical OR operation.
Given is the complete command
$ find . \( -name "*.bash" -o -name "*.txt" \) -mtime +180 -size +2k -exec ls -lh <> \;
In the above example we’ve used -o to perform a logical OR operation for the file extensions but the other conditions are applied as an implicit logical AND operation.
It is recommended that you enclose the file extensions in a bracket, and also use the \ ( backslash) escape character as in the command.
I’ve tried the command it without using the braces and it did not work.
Could even have a combination of multiple OR conditions like we see in the following example:
$ find . \( -name "*.bash" -o -name "*.txt" \) \( -mtime +180 -o -mtime -10 \) -size +2K -exec ls -ltr <> \;
Here I’ve just modified the previous example slightly to add an OR condition with our -mtime (modified time) criteria to search for files modified more than 180 days ago or less than 10 days ago.
Logical NOT Examples
We’ve seen logical AND and logical OR operations. Now we’ll take a look at logical NOT i.e we’ll perform a negation search.
To negate a search criterion we proceeded the search criteria with an exclamation ( ! ) symbol.
Example to find list all files that were modified in the last 30 days and exlude .txt extension
$ find . -type f ! -name "*.txt" -mtime -30 -exec ls -l <> \;
Conclusion
This article, we showed you some examples where you could use the capabilities provided by find and perform some interesting and highly customized search operations.
We hope you found this article useful and look forward towards your feedback.
Related Articles
Thanks for your wonderful Support and Encouragement
More than 40000 Techies in our community do you want part of it Join Now
I am a system administrator who loves to learn and share my knowledge with the community. I’ve been working in the IT industry since 2011.
Команда find Linux
find это мощный инструмент для работы с файлами.
С его помощью можно задавать различные составные условия для дальнейших действий над файлами.
Часто ипользуется как первый шаг перед копированием, перемещением, удалением, изменением файлов, соответсвующих определённым условиям.
В этой статье вы можете познакомится с основами применения find. Про применение find совместно с grep , sed , xargs и другими утилитами вы можете прочитать в статье «Продвинутые методы работы с find»
Поиск
Найти и вывести на экран все файлы в директории
find
find .
find . -print
-name: Поиск по имени
Найти по полному имени в текущей директории
find . -name ‘heihei.log‘
find . -iname ‘heihei.log‘
Поиск по расширению
Найти по расширению файла с помощью wildcard *
Ищем в /usr/share/doc все pdf файлы
find /usr/share/doc -name ‘*.pdf‘
-not: обратное условие
Найти в текущей директории все файлы кроме php
find . -not -name ‘*.php‘
find . ! -name ‘*.php‘
Несколько условий вместе
Найти все файлы, которые начинаются с log но не имеют расширения .txt
find . -name «log*» ! -name ‘*.txt‘
-o: Логическое или
Найти либо .html либо .php файлы
find . -name ‘*.html‘ -o -name ‘*.php‘
Найти и скопировать
Найти и сразу скопировать в текущую директорию
find /usr/share/doc -name ‘*.pdf‘ -exec cp <> . \;
Найти в текущей директории
Удалить из текущей директории
find -name ‘*.pdf‘ -delete
Поиск по типу
Чтобы найти только файлы определённого типа выполните find с опцией type.
Например, что найти все ссылки в директории /etc
Подробнее о файлах в Linux читайте в статье «Типы файлов в Linux»
Уровни вложенности
Найти все ссылки только на верхнем уровне вложенности
find /etc -maxdepth 1 -type l
Поиск по размеру файла
Filesystem Size Used Avail Use% Mounted on /dev/sda1 1014M 194M 821M 20% /boot
Найти обычные файлы определённого размера
Чтобы найти обычные файлы нужно использовать -type f
find /boot -size +20000k -type f
find: ‘/boot/efi/EFI/centos’: Permission denied find: ‘/boot/grub2’: Permission denied /boot/initramfs-0-rescue-389ee10be1b38d4281b9720fabd80a37.img /boot/initramfs-3.10.0-1160.el7.x86_64.img /boot/initramfs-3.10.0-1160.2.2.el7.x86_64.img
Файлы бывают следующих типов:
— : regular file
d : directory
c : character device file
b : block device file
s : local socket file
p : named pipe
l : symbolic link
find /boot -size +10000k -type f
find: ‘/boot/efi/EFI/centos’: Permission denied find: ‘/boot/grub2’: Permission denied /boot/initramfs-0-rescue-389ee10be1b38d4281b9720fabd80a37.img /boot/initramfs-3.10.0-1160.el7.x86_64.img /boot/initramfs-3.10.0-1160.el7.x86_64kdump.img /boot/initramfs-3.10.0-1160.2.2.el7.x86_64.img /boot/initramfs-3.10.0-1160.2.2.el7.x86_64kdump.img
То же самое плюс показать размер файлов
find /boot -size +10000k -type f -exec du -h <> \;
find: ‘/boot/efi/EFI/centos’: Permission denied find: ‘/boot/grub2’: Permission denied 60M /boot/initramfs-0-rescue-389ee10be1b38d4281b9720fabd80a37.img 21M /boot/initramfs-3.10.0-1160.el7.x86_64.img 13M /boot/initramfs-3.10.0-1160.el7.x86_64kdump.img 21M /boot/initramfs-3.10.0-1160.2.2.el7.x86_64.img 14M /boot/initramfs-3.10.0-1160.2.2.el7.x86_64kdump.img
Поиск по началу имени файла
Обратите внимание, что в find, в отличие от grep , ставить перед началом названия никаких символов не нужно.
find -name ‘topb*‘
Поиск по части имени файла
Найти в проекте topbicyle все директории с qa в названии
find topbicycle/ -name ‘*qa*‘ -type d
-perm: поиск по правам доступа
find . -type f -perm 0600
find . -type f ! -perm 0600
-path: поиск путей
Если мне нужно посмотреть содержимое директорий /code/php и /code/python
Пример укороченного результата
-prune: ограничить глубину
С помощью path можно посмотреть содержимое всех поддиректорий code на букву p /code/p*
Если нужно посмотреть только поддиректории верхнего уровня — используется -prune
find . -path «./code/p*» -prune
Получили только поддиректории без их содержимого
Исключить директорию из поиска
Из предыдущего параграфа понятно, что с помощью prune можно исключить директорию из поиска.
Пример: найти в ./code все файлы, заканчивающиеся на index.php но проигнорировать поддиректории на p, то есть в директориях python и php не искать.
find ./code -path «./code/p*» -prune -false -o -name «*index.php»
./code/js/errors/index.php ./code/js/index.php ./code/c/index.php ./code/cpp/index.php ./code/go/pointers/index.php ./code/go/declare_variable/index.php ./code/go/constants/index.php ./code/go/index.php ./code/java/index.php ./code/dotnet/index.php ./code/ruby/index.php ./code/theory/index.php ./code/index.php
-false нужен чтобы не выводить проигнорированные директории.
Ещё один способ исключить директорию из поиска
find ./code -name «*.php« -not -path «./code/p*»
How to ignore certain filenames using «find»?
which searches the contents of all of the files at and below the current directory for the specified SearchString. As a developer, this has come in handy at times. Due to my current project, and the structure of my codebase, however, I’d like to make this BASH command even more advanced by not searching any files that are in or below a directory that contains «.svn», or any files that end with «.html» The MAN page for find kind of confused me though. I tried using -prune, and it gave me strange behavior. In an attempt to skip only the .html pages (to start), I tried :
find . -wholename './*.html' -prune -exec grep 'SearchString' <> /dev/null \;
and did not get the behavior I was hoping for. I think I might be missing the point of -prune. Could you guys help me out? Thanks
@emanuele Hi, welcome to SuperUser (and the Stack Exchange network). This is a question I asked, and that was answered, 2 1/2 years ago. Typically, if you would like to add an answer to the question, please do so by scrolling to the bottom and answering there, instead of in a comment. Since this question already has an accepted answer (the one with the green checkmark), it’s unlikely that your answer is going to get much attention, however. FYI.
Hi, it is not an answer to your question. It is only a tip, as you stated in preamble that use find to search inside a file.
FWIW, -name ‘*.*’ does not find all files: only those with a . in their name (the use of *.* is typically an DOS-ism, whereas in Unix, you normally use just * for that). To really match them all, just remove the argument altogether: find . -exec . . Or if you want to only apply grep to files (and skip directories) then do find . -type f -exec . .
5 Answers 5
You can use the negate (!) feature of find to not match files with specific names:
find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' <> /dev/null \;
So if the name ends in .html or contains .svn anywhere in the path, it will not match, and so the exec will not be executed.
@Paul The desired effect is to exclude «files that are in or below a directory that contains .svn «, so path (or wholename , but path is more portable) is more accurate than name for the answer. They questioner doesn’t appear to have any files with .svn in the name.
I’ve had the same issue for a long time, and there are several solutions which can be applicable in different situations:
- ack-grep is a sort of «developer’s grep » which by default skips version control directories and temporary files. The man page explains how to search only specific file types and how to define your own.
- grep ‘s own —exclude and —exclude-dir options can be used very easily to skip file globs and single directories (no globbing for directories, unfortunately).
- find . \( -type d -name ‘.svn’ -o -type f -name ‘*.html’ \) -prune -o -print0 | xargs -0 grep . should work, but the above options are probably less of a hassle in the long run.
The following find command does prune directories whose names contain .svn , Although it does not descend into the directory, the pruned path name is printed . ( -name ‘*.svn’ is the cause!) ..
You can filter out the directory names via: grep -d skip which silently skips such input «directory names».
With GNU grep, you can use -H instead of /dev/null . As a slight side issue: \+ can be much faster than \; , eg. for 1 million one-line files, using \; it took 4m20s, using \+ it took only 1.2s.
The following method uses xargs instead of -exec , and assumes there are no newlines \n in any of your file names. As used here, xargs is much the same as find’s \+ .
xargs can pass file-names which contain consecutive spaces by changing the input delimiter to ‘\n’ with the -d option.
This excludes directories whose names contain .svn and greps only files which don’t end with .html .
find . \( -name '*.svn*' -prune -o ! -name '*.html' \) | xargs -d '\n' grep -Hd skip 'SearchString'