Главная

Friday, 18 October 2019

Команды поиска в Linux.

Всем привет.

Искать надо постоянно. Особенно в Linux. И тогда встает вопрос - чем же искать? Ниже самые популярные инструменты командной строки.

Find - позволяет отыскивать файлы по имени, дате создания или модификации, владельцу (обычно, это создатель файла), объему и даже типу файла по всем каталогам на текущий момент.

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

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

Grep осуществляет поиск заданной строки текста в файлах.

Объединяйте ваши команды с операторами управления.

Вы, вероятно, уже знаете, что в большинстве оболочек вы можете комбинировать команды в одной командной строке с помощью использования точки с запятой (;) между ними. Точка с запятой - это управляющий оператор оболочки, и хотя он предназначен, для того чтобы связывать множественные отдельные команды в единую командную строку, его применение не всегда возможно. Например, предположим, что вы используете точку с запятой для объединения двух команд, в которых выполнение второй команды всецело зависит от успешного окончания первой. Если первая команда не выполняется так, как вы ожидаете, вторая команда все же запускается - и терпит неудачу. Вместо этого, используйте более подходящий оператор управления (некоторые описаны в данной статье). Если ваша оболочка их поддерживает, к ним стоит привыкнуть.

Запуск команды только в том случае, если другая команда возвратила нулевое значение (retcode = 0)

Используйте оператор управления && для объединения двух команд таким образом, что вторая команда будет выполняться, только если первая возвратила нулевое значение. Другими словами, если первая команда выполняется успешно, вторая команда тоже запускается. Если первая команда не выполняется, то вторая команда не запускается совсем. Например:

Листинг 1. Пример хорошего метода работы #3: Объединяйте команды с операторами управления
~ $ cd tmp/a/b/c && tar xvf ~/archive.tar

В этом примере содержимое архива извлекается в каталог ~/tmp/a/b/c, если этот каталог существует. Если каталог не существует, команда tar не запустится и из архива ничего не будет извлечено.



Запуск команды только в том случае, если другая команда возвратила ненулевое значение (retcode <> 0)

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

Листинг 2. Еще один пример хорошего метода работы #3: Объединяйте команды с операторами управления
~ $ cd tmp/a/b/c || mkdir -p tmp/a/b/c

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

Листинг 3. Комбинированный пример хорошего метода работы #3: Объединение команд с операторами управления
~ $ cd tmp/a/b/c || mkdir -p tmp/a/b/c && tar xvf -C tmp/a/b/c ~/archive.tar


Объединяйте команды в список.

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

Запуск списка команд в дополнительной оболочке.

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

Листинг 4. Пример хорошего метода работы #6: Запуск списка команд в дополнительной оболочке
~ $ ( cd tmp/a/b/c/ || mkdir -p tmp/a/b/c && \
> VAR=$PWD; cd ~; tar xvf -C $VAR archive.tar ) \
> | mailx admin -S "Archive contents"

В этом примере содержимое архива извлекается в каталог tmp/a/b/c, в то время как вывод сгруппированных команд, включая список извлеченных файлов, отправляется по почте на адрес admin. 

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

Запуск списка команд в текущей оболочке.

Используйте фигурные скобки ({}) для заключения списка команд для запуска в текущей оболочке. Убедитесь, что вы добавили пробелы между скобками и командами, т.к. в противном случае оболочка может неправильно интерпретировать скобки.. Также убедитесь, что после последней команды в списке стоит точка с запятой (;), как в следующем примере:

Листинг 5. Еще один пример хорошего метода работы #6: Запуск списка команд в текущей оболочке
~ $ { cp ${VAR}a . && chown -R guest.guest a && \
> tar cvf newarchive.tar a; } | mailx admin -S "New archive"


Знайте, когда использовать grep для подсчета - а когда от него лучше отказаться.

Избегайте использовать после grep команду wc -l для подсчета количества полученных строк. Опция -c в grep позволяет подсчитать количество строк, которые соответствуют заданным шаблонам и в целом работает быстрее, чем комбинация "wc после grep", как в следующем примере:

Листинг 6. Пример хорошего метода работы #8: Подсчет числа строк с и без grep
~ $ time grep and tmp/a/longfile.txt | wc -l
2811

real    0m0.097s
user    0m0.006s
sys     0m0.032s
~ $ time grep -c and tmp/a/longfile.txt
2811

real    0m0.013s
user    0m0.006s
sys     0m0.005s
~ $

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

Однако, этот пример интересен не только с точки зрения быстродействия – он иллюстрирует еще одну распространенную ошибку. Этот метод подсчета предоставляет только количество строк, в которых найдены соответствия образцу - и хорошо, если это то, что вы ищете. Но в случаях, где строки могут иметь несколько совпадений с конкретным образцом, эти методы не дадут реального числа соответствий образцу. Для подсчета числа совпадений используйте wc. Для начала запустите команду grep с опцией -o, если ваша версия поддерживает это. Эта опция выводит только соответствие образцу, по одному на каждую строку, но не саму строку. Ее нельзя использовать вместе с опцией -c, поэтому используйте wc -l для подсчета числа строк, как в следующем примере:

Пример хорошего метода работы #8: Подсчет числа совпадений с образцом с grep
~ $ grep -o and tmp/a/longfile.txt | wc -l
3402
~ $

В этом случае обращение к wc работает немного быстрее, чем второй вызов grep с фиктивным образцом, позволяющим выполнить сравнение и подсчет каждой строки (как grep -c).

Сравнение определенных полей вывода, не только строк.

Инструмент, подобный awk, предпочтительнее grep, когда вы хотите найти соответствие образцу только в конкретных полях строк вывода, а не во всей этой строке.
Следующий упрощенный пример показывает, как отсортировать только те файлы, которые были изменены в декабре:

Листинг 7. Пример плохого метода работы #9: Использование grep для поиска образца в определенных полях
~/tmp $ ls -l /tmp/a/b/c | grep Dec
-rw-r--r--  7 joe joe  12043 Jan 27 20:36 December_Report.pdf
-rw-r--r--  1 root root  238 Dec 03 08:19 README
-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar
~/tmp $

В этом примере grep фильтрует строки и выводит все файлы, в имени или дате изменения которых содержится Dec. Поэтому такой файл, как December_Report.pdf, подходит, даже если он не был изменен с января. Это, возможно, не то, что вы хотите. Для поиска соответствия образцу в конкретном поле лучше использовать awk, в котором относительный оператор соответствует конкретному полю, как показано в следующем примере

Листинг 8. Пример хорошего метода работы #9: Использование awk для поиска образца в определенных полях
~/tmp $ ls -l | awk '$6 == "Dec"'
-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar
-rw-r--r--  1 root root  238 Dec 03 08:19 README
~/tmp $

Более подробно об использовании awk можно прочитать в разделе Ресурсы. Или черкану про него в следующий раз.


No comments:

Post a Comment

А что вы думаете по этому поводу?