Bash рекурсивный поиск файлов. Команда find: широкие возможности для поиска файлов в Linux. Действия над файлами

Несомненно, при работе с Linux, иногда возникает необходимость поиска файлов с определенными характеристиками. Этими характеристиками могут быть размер или тип файла, права доступа и другое.

Наличие в Linux команды find , во многом помогает справиться с поиском файлов по различным критериям.

Сегодня мы разберем поиск файлов в Linux и приведем основные опции команды find , которые вы сможете применить в своей работе.

Список всех файлов, содержащихся в текущем каталоге и подкаталогах

Главное, что вы должны знать, - как использовать эту команду и состоит в том, что синопсис, который вы находите с помощью команды «найти человека», не очень тихий, потому что если это то, что он говорит. Найти, где смотреть. Эта команда эквивалентна вводу любого из следующего.

Поиск файлов по определенному пути

Поиск файла по имени

Инвертировать критерии поиска. Искать только файлы или только каталоги. Поиск нескольких каталогов. Очень полезно иметь возможность одновременно искать несколько каталогов или маршрутов и добавлять их только в параметры. Луис Армандо Медина Следуй за мной в Твиттере.


Формат команды find :

find путь -опции

где путь - это каталог, в котором произвести поиск. В качестве пути можно указывать следующие значения:

. - поиск в текущем каталоге;

/ - поиск от корневого каталога;

~ - поиск в домашнем каталоге.

Что до опций, то тут гораздо бОльший список, с которым крайне необходимо внимательно ознакомиться (это в будущем очень поможет!). Итак, основные опции команды find :

Поначалу это будет похоже на то, что письмо не имеет большого смысла, и вы никогда его не запомните. Структура команд выглядит так: найдите путь выражения. Путь понятен - этот каталог будет выглядеть ниже. Часто используются, например, тип, владелец. Другим важным вариантом является так называемое действие. Это позволяет нам запускать любую системную команду и передавать ее в файл в качестве параметра. Наконец, у нас есть операторы для складывания выражений.

Мы сосредоточимся на практических демонстрациях. Обращается к диску для всех каталогов, называемых экспериментами. Мы должны рассматривать запись так, чтобы она не интерпретировалась оболочкой. Если мы хотим найти подкаталог в текущем каталоге и не переходим через рекурсивно.

-name - поиск файлов по имени, используя приведенный шаблон;

-user - поиск файлов, принадлежащих указанному пользователю;

-group - поиск файлов, принадлежащих указанной группе;

-perm - поиск файлов с указанным режимом доступа;

-type - поиск файлов определенного типа. Типов тоже достаточно:

  • b - специальный блочный файл;
  • d - каталог;
  • c - специальный символьный файл;
  • f - обычный файл;
  • l - символическая ссылка;
  • p - именованный канал;
  • s - сокет.
-size n - поиск файлов с размером n единиц;

-mtime -n +n - поиск файлов, содержание которых изменялось менее чем (-) или более чем (+) дней назад.

Также интересен поиск по количеству файлов и размерам. Этот пример находит все в домашнем каталоге, который был изменен за последние семь дней. Все изменилось более семи дней назад. Находит в текущем каталоге все файлы, которые были изменены перед файлом.

Пустые фигурные скобки будут заменены на путь к найденному файлу. Обратная косая черта перед точкой с запятой важна. Но точка с запятой - это символ, который обычно отделяет команды. При запуске точка с запятой будет пониматься как разделитель команд. Поэтому нам нужно обрабатывать его с помощью \\ или писать как;. Пример будет найден в действии. каталог и подкаталоги для всех файлов и перечисляет детали. Предыдущий пример показывает нам силу иска.

Рассмотрим некоторые примеры применения команды find :

Наиболее часто применяемой опцией является опция -name , которая производит поиск файлов по имени.

Примеры с опцией -name :

$ find /mnt/usb -name "*.mp3" -print

произведет поиск всех файлов (об этом свидетельствует знак *), имеющих расширение.mp3 на USB-устройстве, смонтированном в каталог /mnt/usb.

$ find ~ -name "test*" -print

выведет на экран список файлов домашнего каталога, начинающихся на test.

Если вам надо найти файлы, начинающиеся с определенных букв (к примеру, от a до j), то здесь будет удобно применить регулярные выражения, которые крайне удобны в работе:

$ find / -name "*" -print

Вышеуказанная команда позволит отыскать все файлы в системе, начинающиеся с букв от a до j.

Поиск файлов с определенными режимами доступа

Если потребуется найти файлы, имеющие определенные режимы доступа, вам поможет опция -perm , которая легко в этом поможет.

К примеру, выполним поиск файлов с режимом доступа 775 (владелец и группа имеют полные права и ограничение на запись имеют остальные пользователи), находящихся в текущем каталоге:

$ find . -perm 775 -print

Выполняя поиск при помощи find с опцией -perm можно использовать и другой способ - можно перед значением режима поставить дефис и тогда будет произведен поиск файлов, для которых установлены все указанные биты разрешений. Причем, остальные биты в этом случае игнорируются.

К примеру, найдем файлы, к которым пользователи группы имеют полный доступ:

$ find . -perm -070 -print

Вместо знака дефиса, можно указать знак плюса. В этом случае будет произведен поиск файлов, у которых установлен хотя бы один из указанных битов разрешений. Остальные биты при этом игнорируются.

Поиск файлов определенного пользователя или группы

Поиск файлов какого-либо определенного пользователя крайне прост в своей реализации. Для этого достаточно выполнить команду:

$ find / -user admin -print

Вышеуказанная команда произведет поиск файлов в системе, принадлежащих пользователю admin.

Для того, чтобы найти файлы, принадлежащие определенной группе (к примеру managers), выполним команду:

$ find / -group managers -print

Для поиска файлов несуществующих пользователей или групп можно воспользоваться опциями -nouser и -nogroup :

$ find / -nouser -print

$ find / -nogroup -print

Поиск файлов определенного типа

Одной из удобных возможностей команды find , является возможность поиска файлов определенного типа. Рассмотрим варианты использования опции -type :

Поиск символических ссылок в каталоге /etc:

$ find /etc -type l -print

Вывод на экран списка каталогов, присутствующих в каталоге /mnt/raid

$ find /mnt/raid -type d -print

Поиск файлов определенного размера

Опция -size позволяет произвести поиск файлов определенного размера и имеет следующий вид при выполнении:

$ find . -size 2000k -print

Вышеуказанная команда отыщет и отобразит на экране файлы размером 2 мегабайта, находящийся в текущем каталоге. Если, к примеру, необходимо найти файлы размером менее 500 килобайт, то вид команды будет следующий:

$ find . -size -500k -print

Если нужно найти файлы размером более 600 мегабайт, то применим команду:

$ find / -size +600M -print

Поиск файлов с использованием опции -mtime

Опция -mtime позволит вам найти файлы, изменявшиеся в какой-то срок времени.

К примеру, у нас встала задача поиска файлов, находящихся в каталоге /mnt/raid/upload , и изменявшихся за последние 5 дней. В этом нам поможет команда:

$ find /mnt/raid/upload -mtime -5 -print

Если нам необходимо обратное, к примеру, отыскать файлы, которые не изменялись неделю, применим команду:

$ find /mnt/raid/upload -7 -print

Команда find является крайне удобным инструментом для поиска файлов и может использоваться также и для поиска файлов на дисках NFS (сетевых файловых системах), но в этом случае необходимо учесть, что времени на поиск чего-либо на NFS уйдет гораздо больше, чем на локальных дисках.

В этой статье мы рассмотрели лишь основные опции команды find, которые помогут вам в вашей работе. Используйте то, что удобно и не переживайте по пустякам!

В серверной среде работа с командной строкой занимает много времени. Часто используется оболочка bash – командная оболочка по умолчанию большинства дистрибутивов.

Вероятно, во время терминальной сессии общие команды будут повторяться часто, а вариации данных команд – еще чаще. Конечно, сначала набирать каждую команду вручную очень полезно, так как это – лишняя возможность попрактиковаться, но в какой-то момент это начинает надоедать и раздражать.

К счастью, bash-оболочка имеет некоторые довольно хорошо разработанные функции истории. Умение продуктивно использовать и управлять историей в bash позволяет тратить меньше времени на ввод команд, и тем самым увеличивает объем выполненной работы. Как известно, среди разработчиков популярен так называемый принцип DRY (Don’t Repeat Yourself). Продуктивное использование истории в bash помогает работать с информацией согласно данному принципу.

Это руководство демонстрирует все функции на VPS с Ubuntu 12.04, но почти все современные дистрибутивы Linux будут работать подобным образом.

Настройки истории в bash

Прежде чем использовать историю, нужно отредактировать некоторые настройки bash, чтобы сделать ее более применимой.

Bash позволяет редактировать количество предыдущих команд, которые нужно сохранить в истории. Для этого в bash есть две отдельные опции: параметр «HISTFILESIZE» задает количество команд, хранящихся в файле истории, а «HISTSIZE» указывает количество команд, которое сохраняется в памяти для текущей сессии.

Это означает, что в памяти можно установить разумные пределы размера истории для текущего сеанса, а также хранить более объемную историю на диске для дальнейшего использования.

По умолчанию bash устанавливает очень умеренные значения этих параметров, поэтому их необходимо расширить, чтобы иметь возможность использовать более полную историю. Некоторые дистрибутивы уже увеличили значения параметров истории по умолчанию.

Чтобы изменить данные опции, откройте файл «~/.bashrc» с помощью редактора:

Найдите опции «HISTSIZE» и «HISTFILESIZE». Если значения для них установлены, измените их. Если таких параметров в данном файле нет, внесите их. Данное руководство может обойтись 10000 строк для диска и 5000 строк, сохраненных в памяти. Это достаточно скромные значения для большинства систем, но даже их придется понизить, если они влияют на производительность:

HISTSIZE=5000
HISTFILESIZE=10000

По умолчанию bash пишет историю в конце каждой сессии, переписывая и обновляя уже существующий файл. Это значит, что при работе в нескольких bash-сессиях будет сохранена только история последней завершенной сессии.

Это можно обойти, установив параметр «histappend», который будет добавлять историю, а не перезаписывать её. Возможно, он уже установлен​​; в противном случае его можно активировать, добавив следующую строку:

shopt -s histappend

Чтобы bash вносил команды в историю сразу, не дожидаясь завершения сессии (чтобы команды одного терминала сразу же были доступны в другом), можно установить или добавить команду «history –a» для опции «PROMPT_COMMAND», которая содержит команды, которые выполняются перед каждой новой командной строкой.

Но для правильной работы такой команды нужна уловка. В файл истории нужно сразу добавить «history –a», затем очистить текущую историю данной сессии с помощью «history –c», после этого прочесть отредактированный файл истории и вернуться в историю данной сессии с помощью «history –r».

Это выглядит примерно так:

export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Завершив эту операцию, сохраните изменения и закройте файл.

Чтобы активировать изменения, выйдите из системы и войдите снова, либо используйте команду source на данный файл, набрав:

source ~/.bashrc

Просмотр предыдущей истории в Bash

Для просмотра истории в Bash используется команда «history». Она выводит предыдущие команды, по команде на строку. В большинстве случаев она должна вывести количество строк, установленное значением «HISTSIZE». На данный момент команд не так много:

history
. . .
43 man bash
44 man fc
45 man bash
46 fc -l -10
47 history
48 ls -a
49 vim .bash_history
50 history
51 man history
52 history 10
53 history

Также она выводит порядковый номер команды. Каждая команда связана с номером для удобства использования.

Вывод можно сократить, указав количество команд после «history». Например, если нужно вывести только последние 5 введенных команд, можем набрать:

history 5
50 history
51 man history
52 history 10
53 history
54 history 5

Чтобы найти в истории все команды, которые содержат определенную строку, можно просто использовать grep после символа вертикальной черты. Например, чтобы найти строки, содержащие «cd», наберите:

history | grep cd
33 cd Pictures/
37 cd ..
39 cd Desktop/
61 cd /usr/bin/
68 cd
83 cd /etc/
86 cd resolvconf/
90 cd resolv.conf.d/

Запуск команд из истории в Bash

Научиться выводить команды, конечно, полезно, но, кроме использования порядкового номера команд, это почти ничего не дает. Для вызова любой предыдущей команды нужно использовать специальный синтаксис.

Вызвать любую из предыдущих команд можно, введя ее номер и поставив перед ним восклицательный знак «!». Опираясь на приведенный выше пример истории, можно быстро вывести оперативную страницу руководства, просто введя:

Это немедленно вызовет и выполнит команду в истории под номером 51.

Можно также выполнять команды относительно текущей позиции. Это делается с помощью синтаксиса «!-n», где «n» нужно заменять номером команды, которую нужно выполнить.

К примеру, если нужно вывести и выполнить предпоследнюю набранную команду, то можно набрать «!-2». Итак, если было выведено содержимое длинного пути к каталогу, а затем введена команда echo, и теперь нужно снова вывести путь, то сессия может выглядеть следующим образом:

ls /usr/share/doc/manpages
echo hello
!-2 # lists the contents again

Чтобы повторно выполнить последнюю команду, вместо использования «!-1» в bash можно использовать «горячую» команду «!!», что выполняет:

Многие используют это в случае, если они набрали команду, требующую привилегий sudo. При наборе «sudo !!» команда будет перевыполнена с привилегиями sudo. Такая сессия выглядит примерно так:

touch /etc/hello
touch: cannot touch `/etc/hello": Permission denied
sudo !!
sudo touch /etc/hello
password for demouser:

Данный пример демонстрирует еще одно свойство этого полезного синтаксиса. По сути, это простая замена, потому при необходимости его можно включать в другие команды.

Прокрутка истории в Bash

Прокрутить историю в Bash, выводя каждую последующую команду в командной строке для редактирования, можно несколькими способами.

Наиболее распространенным способом является нажатие клавиши со стрелкой вверх в командной строке.

Каждое дополнительное нажатие этой клавиши будет возвращать на шаг назад в истории командной строки. Чтобы изменить направление, используйте клавишу со стрелкой вниз, которая прокручивает историю вплоть до последней командной строки.

Вместо клавиш со стрелками можно использовать сочетания клавиш: «CTRL-p» для прокрутки истории назад, и «CTRL-n» для прокрутки вперед.

Чтобы вернуться к текущей командной строке, можно использовать «Meta->». В большинстве случаев «meta» и символ «>» заменяют комбинацию «ALT-Shift-.». Это очень полезно в случае, если текущая командная строка находится достаточно далеко.

Чтобы переместиться к первой строке истории, используйте обратный манёвр, «Meta-<». Обычно это сочетание замещает «ALT-Shift-,».

В качестве подведения итогов ниже приведен список наиболее важных клавиш перемещения по истории:

  • Клавиша со стрелкой вверх: прокрутка истории назад;
  • CTRL p : прокрутка истории назад;
  • Клавиша со стрелкой вниз: прокрутка истории вперед;
  • CTRL n : прокрутка истории вперед;
  • ALT Shift -. : перемещение в конец истории (к последней введенной команде);
  • ALT Shift -, : перемещение в начало истории (к первой введенной команде).

Поиск по истории в Bash

Хотя использование комбинации «history | grep» – самый простой способ выполнения некоторых процедур, его работа во многих ситуациях далеко не идеальна.
Bash имеет функции поиска по истории. К примеру, часто используется поиск по истории в обратном направлении (сначала выводятся самые «свежие» результаты) с помощью сочетания клавиш «Ctrl-r».

Например, можно ввести «Ctrl-r» и набрать часть предыдущей команды. Необходимо набрать только часть команды. Если же введенное значение совпало с ненужной командой, можно снова нажать «Ctrl-r», чтобы вывести следующий результат.

Если нужная команда была случайно пропущена, можно изменить направление поиска при помощи комбинации «CTRL-s». Это также полезно при перемещении по истории, описанном в предыдущей главе, для поиска вперед.

Примечание : во многих терминалах, комбинация «CTRL-s» блокирует сессию терминала. То есть, при попытке использовать ее для поиска она будет «замораживать» терминал. Чтобы разблокировать сессию, просто наберите «Ctrl-q».

Эти функции приостановки и возобновления сессии в большинстве современных терминалов не нужны, потому их можно отключить, набрав:

Теперь нужно внести это в файл «~/.bashrc», чтобы обеспечить постоянное выполнение команды.

Теперь эта комбинация поиска будет работать верно.

Поиск по введенной части команды

Распространенный способ поиска – ввести часть команды, выяснить, была ли она выполнена ранее, и затем найти ее в истории.

Как правильно выполнить поиск, используя уже внесенные в командную строку данные? Переместите курсор в начало строки при помощи «CTRL-a», затем вызовите обратный просмотр истории «CTRL-r», вставьте текущую строку в поиск с помощью «CTRL-y», и снова используйте «CTRL-r» для обратного поиска.

К примеру, необходимо обновить кэш пакета в Ubuntu. Эта команда уже была выполнена, но чтобы проверить, так ли это, можно набрать sudo:

На данном этапе видно, что эта команда точно уже выполнялась недавно. Теперь нажмите:

Это переведет курсор в начало строки.

Это вызовет обратный последовательный поиск по истории. Это действие имеет побочный эффект – оно копирует все содержимое командной строки, что находится после текущего положения курсора, и вставляет его в буфер обмена.

Это вставляет только что скопированные из командной строки части команды в поиск.

Теперь нужно снова запустить обратный поиск по истории, чтобы найти команды, содержащие указанную часть.

Сначала эта процедура кажется довольно запутанной, но к ней просто нужно привыкнуть. Она чрезвычайно полезна в те моменты, когда половина сложных команд была введена, и теперь для завершения работы нужна история.

Кроме того, все эти действия можно объединить в одно:

Продвинутое использование истории в bash

Рассмотрев основные техники использования истории, существующие в bash. Среди них:

  • !! : вывести последнюю команду;
  • ! n : перейти к команде с порядковым номером «n»;
  • !- n : перейти к команде, которая была под номером «n» перед выполнением последней команды.

Определители события

Три вышеперечисленных комбинации называются определителями события . По сути, это способ вызова предыдущих команд из истории при помощи определенных критериев.

К примеру, чтобы выполнить последнюю команду «ssh», можно использовать:

Это действие ищет строки, которые начинаются с «ssh». Чтобы найти последовательность, которая находится не в начале команды, можно ввести символ «?» перед и после последовательности. К примеру, чтобы повторить последнюю команду «apt-cache search», нужно набрать:

Также можно использовать вариации вывода последней команды («!!»). Выполнить быстрый поиск и замену, набрав:

^original^replacement^

Это вызовет последнюю команду (как «!!»), ищет совпадение со значением «original», и заменяет его значением «replacement». Затем команда будет выполнена.

Это очень удобно применять при необходимости исправить орфографические ошибки. К примеру:

cat /etc/hosst
cat: /etc/hosst: No such file or directory
^hosst^hosts^

Определители слов

После определителей события можно добавить символ двоеточия (:), а затем внести определитель слова , чтобы выбрать часть совпавшей команды.

Это работает путем деления команды на «слова» — участки, разделенные пробелами. Это открывает новые возможности взаимодействия с параметрами команд.

Сама команда нумеруется нулем, первый аргумент – 1, и так далее.

К примеру, можно вывести содержимое каталога, а затем изменить его таким образом:

ls /usr/share/doc/manpages
cd !!:1

Если данная операция выполняется с последней запущенной командой, то эту комбинацию можно сжать, убрав второй «!» и двоеточие:

Это будет работать тем же образом.

На первый аргумент можно сослаться при помощи символа «^», а на последний аргумент – «$». Эти символы намного полезнее при работе с диапазонами, а не порядковыми номерами. К примеру, извлечь все аргументы из предыдущей команды в новую можно тремя способами:

!!:1*
!!:1-$
!!:*

Символ звездочки «*» применяется для обозначения вывода любых данных, кроме исходной команды. Аналогично, можно использовать номер слова, указав после него *, чтобы обозначить, что все после указанного слова должно быть также включено.

Модификаторы

Последнее, чем можно дополнить поведение вызванной строки истории – это изменение поведения вызова для управления самим текстом. Модификаторы вносятся после дополнительного символа «:» в конце строки.

К примеру, сократить путь к файлу можно при помощи модификатора «h» (что значит «head»), который удаляет путь до последнего символа слеша (/). Запомните: это не будет работать должным образом при необходимости сократить путь к каталогу, который заканчивается символом слеша.

Это часто используется при изменении файла и необходимости перейти в его каталог, чтобы выполнить операции на связанные с ним файлы.

cat /usr/share/doc/manpages/copyright

После этого нужно перейти в каталог. Это можно сделать при помощи команды «cd» на строку параметров, «отрезая» имя файла в конце.

cd !!:$:h
pwd
/usr/share/doc/manpages

Можно также выполнить обратную процедуру, сокращая путь и используя только имя файла, при помощи модификатора «t» (что значит «tail»). Для примера можно поискать последнюю команду «cat», используя флаг «t», чтобы оставить только имя файла.

Можно также просто оставить полный путь, и команда будет работать должным образом. Но иногда это не так. К примеру, если при работе с файлом, вложенным в несколько подкаталогов текущего каталога, использовать относительный путь, и изменить подкаталог с помощью модификатора «h», то использовать относительный путь к данному файлу больше не получится.

Еще один очень полезный модификатор – «r», удаляющий хвостовой суффикс вида «.xxx». Это полезно при использовании команды «tar» для распаковки файла и необходимости после этого перейти в каталог. Предполагая, что имя каталога совпадает с именем файла, можно выполнить что-то вроде:

tar xzvf long-project-name.tgz
cd !!:$:r

Если tarball использует расширение tar.gz вместо tgz, просто введите модификатор дважды:

tar xzvf long-project-name.tar.gz
cd !!:$:r:r

Похожий модификатор, «е», удаляет все, кроме хвостового расширения.

Если вызываемую команду нужно просто найти, а не выполнить, можно использовать модификатор «p», чтобы bash снова отобразил команду.

Это полезно, если нужно убедиться в правильности выбранного отрывка истории. Кроме того, этот модификатор поместит выбранную команду в историю на случай если она нуждается в дальнейшем редактировании.

К примеру, команда «find» была ранее запущена на домашний каталог, а теперь ее нужно запустить из этого каталога (/). Проверить, правильно ли выполнена подстановка, можно следующим образом (при условии, что данная команда имеет №119):

find ~ -name "file1" # original command
!119:0:p / !119:2*:p
find / -name "file1"

Если же команда была выведена верно, ее можно запустить при помощи:

Есть и более простой способ выполнения подстановки в командах: для этого можно использовать синтаксис s/original/new/

К примеру, описанное выше действие можно выполнить так:

Это заменит первый экземпляр поискового шаблона. Чтобы выполнить подстановку на каждое совпадение, используйте модификаторы «g» и «s». К примеру, чтобы создать файлы по имени » file1″, «file2» и «file3» и каталоги «dir1», «dir2», «dir3», нужно использовать:

touch file1 file2 file3
mkdir !!:*:gs/file/dir/

Итоги

Данное руководство помогает овладеть основными понятиями использования истории. Конечно, некоторые из описанных функций будут полезны в редких случаях, но знать о них и уметь их использовать также необходимо.

В целом, все описанные возможности использования истории могут существенно ускорить работу.

Tags: ,