- How to pipe list of files returned by find command to cat to view all the files
- 15 Answers 15
- Modern version
- Classic version
- Tweaking the results from grep
- Поиск в Linux с помощью команды find
- Общий синтаксис
- Описание опций
- Примеры использования find
- Поиск файла по имени
- Поиск по дате
- По типу
- Поиск по правам доступа
- Поиск файла по содержимому
- С сортировкой по дате модификации
- Лимит на количество выводимых результатов
- Поиск с действием (exec)
- Чистка по расписанию
- Find files and echo content on shell
- 3 Answers 3
- How to use «cat» command on «find» command’s output?
- 4 Answers 4
How to pipe list of files returned by find command to cat to view all the files
I am doing a find to get a list of files. How do I pipe it to another utility like cat so that cat displays the contents of all those files? Afterwards, I’d use grep on that to search some text in those files.
15 Answers 15
- Piping to another process (although this won’t accomplish what you said you are trying to do):
The backquotes work great and is more generalized, you can use this to cat a list of files from a file as well.
Note that modern versions of find allow you to write: find . -name ‘*.foo’ -exec cat <> + , where the + indicates that find should group as many file names as convenient into a single command invocation. This is quite useful (it deals with spaces etc in file names without resorting to -print0 and xargs -0 ).
Just to add on @stewSquared s answer: To find all lines in files that contain a certain string, do find . -name ‘*.foo’ | xargs cat | grep string
Modern version
POSIX 2008 added the + marker to find which means it now automatically groups as many files as are reasonable into a single command execution, very much like xargs does, but with a number of advantages:
- You don’t have to worry about odd characters in the file names.
- You don’t have to worry about the command being invoked with zero file names.
The file name issue is a problem with xargs without the -0 option, and the ‘run even with zero file names’ issue is a problem with or without the -0 option — but GNU xargs has the -r or —no-run-if-empty option to prevent that happening. Also, this notation cuts down on the number of processes, not that you’re likely to measure the difference in performance. Hence, you could sensibly write:
find . -exec grep something <> +
Classic version
find . -print | xargs grep something
If you’re on Linux or have the GNU find and xargs commands, then use -print0 with find and -0 with xargs to handle file names containing spaces and other odd-ball characters.
find . -print0 | xargs -0 grep something
Tweaking the results from grep
If you don’t want the file names (just the text) then add an appropriate option to grep (usually -h to suppressing ‘headings’). To absolutely guarantee the file name is printed by grep (even if only one file is found, or the last invocation of grep is only given 1 file name), then add /dev/null to the xargs command line, so that there will always be at least two file names.
Поиск в Linux с помощью команды find
Обновлено: 01.02.2022 Опубликовано: 25.07.2016
Утилита find представляет универсальный и функциональный способ для поиска в Linux. Данная статья является шпаргалкой с описанием и примерами ее использования.
Общий синтаксис
— путь к корневому каталогу, откуда начинать поиск. Например, find /home/user — искать в соответствующем каталоге. Для текущего каталога нужно использовать точку «.». — набор правил, по которым выполнять поиск. * по умолчанию, поиск рекурсивный. Для поиска в конкретном каталоге можно использовать опцию maxdepth.
Описание опций
Также доступны логические операторы:
Оператор | Описание |
---|---|
-a | Логическое И. Объединяем несколько критериев поиска. |
-o | Логическое ИЛИ. Позволяем команде find выполнить поиск на основе одного из критериев поиска. |
-not или ! | Логическое НЕ. Инвертирует критерий поиска. |
Полный набор актуальных опций можно получить командой man find.
Примеры использования find
Поиск файла по имени
* в данном примере будет выполнен поиск файла с именем file.txt по всей файловой системе, начинающейся с корня /.
2. Поиск файла по части имени:
* данной командой будет выполнен поиск всех папок или файлов в корневой директории /, заканчивающихся на .tmp
а) Логическое И. Например, файлы, которые начинаются на sess_ и заканчиваются на cd:
find . -name «sess_*» -a -name «*cd»
б) Логическое ИЛИ. Например, файлы, которые начинаются на sess_ или заканчиваются на cd:
find . -name «sess_*» -o -name «*cd»
в) Более компактный вид имеют регулярные выражения, например:
* где в первом поиске применяется выражение, аналогичное примеру а), а во втором — б).
4. Найти все файлы, кроме .log:
* в данном примере мы воспользовались логическим оператором !.
Поиск по дате
1. Поиск файлов, которые менялись определенное количество дней назад:
* данная команда найдет файлы, которые менялись более 60 дней назад.
find . -mmin -20 -mmin +10 -type f
* найти все файлы, которые менялись более 10 минут, но не более 20-и.
2. Поиск файлов с помощью newer. Данная опция доступна с версии 4.3.3 (посмотреть можно командой find —version).
find . -type f -newermt «2019-11-02 00:00»
* покажет все файлы, которые менялись, начиная с 02.11.2019 00:00.
find . -type f -newermt 2019-10-31 ! -newermt 2019-11-02
* найдет все файлы, которые менялись в промежутке между 31.10.2019 и 01.11.2019 (включительно).
find . -type f -newerat 2019-10-08
* все файлы, к которым обращались с 08.10.2019.
find . -type f -newerat 2019-10-01 ! -newerat 2019-11-01
* все файлы, к которым обращались в октябре.
find . -type f -newerct 2019-09-07
* все файлы, созданные с 07 сентября 2019 года.
find . -type f -newerct 2019-09-07 ! -newerct «2019-09-09 07:50:00»
* файлы, созданные с 07.09.2019 00:00:00 по 09.09.2019 07:50
По типу
Искать в текущей директории и всех ее подпапках только файлы:
* f — искать только файлы.
Поиск по правам доступа
1. Ищем все справами на чтение и запись:
2. Находим файлы, доступ к которым имеет только владелец:
Поиск файла по содержимому
find / -type f -exec grep -i -H «content» <> \;
* в данном примере выполнен рекурсивный поиск всех файлов в директории / и выведен список тех, в которых содержится строка content.
С сортировкой по дате модификации
find /data -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | sort -r
* команда найдет все файлы в каталоге /data, добавит к имени дату модификации и отсортирует данные по имени. В итоге получаем, что файлы будут идти в порядке их изменения.
Лимит на количество выводимых результатов
Самый распространенный пример — вывести один файл, который последний раз был модифицирован. Берем пример с сортировкой и добавляем следующее:
find /data -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | sort -r | head -n 1
Поиск с действием (exec)
1. Найти только файлы, которые начинаются на sess_ и удалить их:
find . -name «sess_*» -type f -print -exec rm <> \;
* -print использовать не обязательно, но он покажет все, что будет удаляться, поэтому данную опцию удобно использовать, когда команда выполняется вручную.
2. Переименовать найденные файлы:
find . -name «sess_*» -type f -exec mv <> new_name \;
find . -name «sess_*» -type f | xargs -I ‘<>‘ mv <> new_name
3. Переместить найденные файлы:
find . -name «sess_*» -type f -exec mv <> /new/path/ \;
* в данном примере мы переместим все найденные файлы в каталог /new/path/.
4. Вывести на экран количество найденных файлов и папок, которые заканчиваются на .tmp:
find /home/user/* -type d -exec chmod 2700 <> \;
* в данном примере мы ищем все каталоги (type d) в директории /home/user и ставим для них права 2700.
6. Передать найденные файлы конвееру (pipe):
find /etc -name ‘*.conf’ -follow -type f -exec cat <> \; | grep ‘test’
* в данном примере мы использовали find для поиска строки test в файлах, которые находятся в каталоге /etc, и название которых заканчивается на .conf. Для этого мы передали список найденных файлов команде grep, которая уже и выполнила поиск по содержимому данных файлов.
7. Произвести замену в файлах с помощью команды sed:
find /opt/project -type f -exec sed -i -e «s/test/production/g» <> \;
* находим все файлы в каталоге /opt/project и меняем их содержимое с test на production.
Чистка по расписанию
Команду find удобно использовать для автоматического удаления устаревших файлов.
Открываем на редактирование задания cron:
0 0 * * * /bin/find /tmp -mtime +14 -exec rm <> \;
* в данном примере мы удаляем все файлы и папки из каталога /tmp, которые старше 14 дней. Задание запускается каждый день в 00:00.
* полный путь к исполняемому файлу find смотрим командой which find — в разных UNIX системах он может располагаться в разных местах.
Find files and echo content on shell
But how can I output the content of each file instead. Thought of something like piping the filename to the cat -command.
3 Answers 3
Use cat within the -exec predicate of find :
find -name '.htaccess' -type f -exec cat <> +
This will output the contents of the files, one after another.
@pbaldauf Do: find . -type f -name file.txt -exec sh -c ‘printf «%s\n%s\n\n» «$1» «$(cat — «$1»)»‘ _ <> \;
See the manual page for find ( man find ).
-exec utility [argument . ] ; True if the program named utility returns a zero value as its exit status. Optional arguments may be passed to the utility. The expression must be terminated by a semicolon (``;''). If you invoke find from a shell you may need to quote the semicolon if the shell would otherwise treat it as a control operator. If the string ``<>'' appears anywhere in the utility name or the arguments it is replaced by the pathname of the current file. Utility will be executed from the directory from which find was executed. Utility and arguments are not subject to the further expansion of shell patterns and constructs. -exec utility [argument . ] <> + Same as -exec, except that ``<>'' is replaced with as many pathnames as possible for each invocation of utility. This behaviour is similar to that of xargs(1).
So, just tack on the -exec switch.
find -type f -name '.htaccess' -exec cat <> +
How to use «cat» command on «find» command’s output?
I want to redirect the output of the find command to cat command so I can print the data of the given file. So for example if the output of find is /aFile/readme then the cat should be interpreted as cat ./aFile/readme . How can I do that instantly ? Do I have to use pipes ? I tried versions of this :
cat | find ./inhere -size 1033c 2> /dev/null
But I guess this is completely wrong? Of course I’m sure that the output is only one file and not multiple files. So how can I do that ? I’ve searched on Google and couldn’t find a solution, probably because I didn’t search right 😛
4 Answers 4
You can do this with find alone using the -exec action:
find /location -size 1033c -exec cat <> +
<> will be replaced by the files found by find , and + will enable us to read as many arguments as possible per invocation of cat , as cat can take multiple arguments.
If your find does not have the standard + extension, or you want to read the files one by one:
find /location -size 1033c -exec cat <> \;
If you want to use any options of cat , do:
find /location -size 1033c -exec cat -n <> + find /location -size 1033c -exec cat -n <> \;
Here I am using the -n option to get the line numbers.
So, If I’m correct : <> is like a variable that in it is stored the output of the find command and after the «+» sign you’re supposed to write the cat parameters ? No ? Edit : Alright you edited your post and now you just answered my question 😛 Thanx man ! Solved !
Command Substitution
Another option is to use Command Substitution. Wrapping a command in $() will run the command and replace the command with its output.
cat $(find ./inhere -size 1033c 2> /dev/null)
cat ./inhere/file1 ./inhere/file2 ./inhere/file3
This is more or less equivalent to using the older style of wrapping commands with back ticks:
cat `find ./inhere -size 1033c 2> /dev/null`
More details from the docs linked above
Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file) .
When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $ , ` , or \ . The first backquote not preceded by a backslash terminates the command substitution. When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.
Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes.
If the substitution appears within double quotes, word splitting and filename expansion are not performed on the results.
See this other answer for some good examples of usage.