Как работает grep?
Я пытаюсь понять, как grep
строительство.
когда я говорю grep "hello" *.*
, значит grep
получить 2 аргумента - (1) строка для поиска, т. е. "привет" и (2) путь *.*
? Или оболочка преобразует *.*
- то grep
могу понять?
где я могу получить исходный код grep
? Я наткнулся на это GNU grep
ссылка. Один из файлов README говорит, что он отличается от unix grep
. Как так?
Я хочу посмотреть источник FreeBSD версии grep
а также Linux версии (если они разные).
4 ответов
оболочка выполняет подстановки (преобразования *
форма для имен файлов). Вы можете увидеть это, если у вас есть простая программа на C:
#include <stdio.h>
int main(int argc, char **argv) {
for(int i=1; i<argc; i++) {
printf("%s\n", argv[i]);
}
return 0;
}
а затем запустите его так:
./print_args *
вы увидите, что он печатает то, что соответствует, а не *
буквально. Если вы вызываете его так:
./print_args '*'
вы увидите, что он получает буквальное *
.
власть grep
магия в теории автоматов. GREP-это аббревиатура от Global Regular Expression Print. И он работает, создавая автомат (очень простая "виртуальная машина": не полная Тьюринга); затем он "выполняет" автомат против входного потока.
автомат представляет собой граф или сеть узлов или состояний. Переход между состояниями определяется анализируемым входным характером. Специальные автоматы как +
и *
работа имея переходы, которые петля обратно к себе. Классы символов, такие как [a-z]
представлены вентилятором: один начальный узел с ветвями для каждого символа выходит на "спицы"; и обычно спицы имеют специальный" переход Эпсилона " в одно конечное состояние, поэтому его можно связать со следующим автоматом, который будет построен из регулярного выражения (строка поиска). Переходы epsilon позволяют изменять состояние без перемещения вперед в строке разыскиваемый.
Edit: похоже, я не очень внимательно прочитал вопрос.
когда вы вводите командную строку, она сначала предварительно обрабатывается оболочкой. Оболочка выполняет псевдоним замен и именем подстановка. После замены псевдонимов (они похожи на макросы) оболочка разбивает командную строку на список аргументов (разделенных пробелами). Этот список аргументов передается в main()
функция исполняемой командной программы в виде целого числа (часто называемый argc) и указатель на NULL-terminated ((void *)0
) массив нулевого завершения (''
) char массивы.
отдельные команды используют свои аргументы, как они хотят. Но большинство программ Unix будут печатать дружественное сообщение справки, если задано -h
аргумент (поскольку он начинается со знака минус, он называется опцией). Программное обеспечение GNU также примет опцию "длинной формы"--help
.
поскольку существует множество различий между различными версиями программы для Unix самый надежный способ узнать точный синтаксис, который требуется задать в самой программе. Если это не говорит вам, что вам нужно (или это слишком загадочно, чтобы понять), вы должны проверить местные man-страницы (man grep
). А для программного обеспечения gnu вы часто можете получить еще больше информации от info grep
.
оболочка расширяется '*.*
' в список имен файлов и передает расширенный список имен файлов в программу, такую как grep
. The grep
сама программа не делает Расширения имен файлов.
так, в ответ на ваш вопрос: grep
не получает 2 аргумента; оболочка преобразует'*.*
' в чем-то grep
могу понять.
GNU grep
отличается от Unix grep
в поддержке дополнительных вариантов, таких как -w
и -B
и -A
.
мне кажется, что FreeBSD использует версию GNU grep
:
как grep видит аргумент подстановочного знака, зависит от вашей оболочки. (Стандартный) Bourne shell имеет переключатель (- f) для отключения имени файла подстановка (см. man pages).
вы можете активировать этот параметр в скрипте с
set -f