Подтвердить что ты не робот

Как работает grep?

Я пытаюсь понять, как работает grep.

Когда я говорю grep "hello" *.*, grep получает 2 аргумента — (1) строка для поиска, т.е. "Привет" и (2) путь *.*? Или оболочка преобразует *.* в нечто, что grep может понять?

Где я могу получить исходный код grep? Я наткнулся на эту ссылку GNU grep. Один из файлов README отличается от unix grep. Как это так?

Я хочу посмотреть источник версии FreeBSD grep, а также версию Linux (если они разные).

4b9b3361

Ответ 1

В оболочке выполняется глобус (преобразование формы * в имена файлов). Вы можете увидеть это, если у вас есть простая программа на 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 '*'

Вы увидите, что он получает буквальный *.

Ответ 2

Сила grep - магия теории автоматов. GREP является аббревиатурой для Global Regular Expression Print. И он работает, создавая автомат (очень простая "виртуальная машина": не Turing Complete); он затем "выполняет" автомат против входного потока.

Автомат - это граф или сеть узлов или состояний. Переход между состояниями определяется входным символом под контролем. Специальные автоматы, такие как + и * работают, имея переходы, которые возвращаются к себе. Классы символов, такие как [a-z], представлены вентилятором: один старт node с ветвями для каждого символа на "спицы"; и обычно спицы имеют специальный "переход эпсилон" в одно конечное состояние, поэтому его можно связать со следующим автоматом, который будет создан из регулярного выражения (строки поиска). Эпсилонные переходы позволяют изменять состояние, не перемещаясь вперед в поисках строки.

Изменить: Похоже, я не очень внимательно прочитал вопрос.

Когда вы вводите командную строку, она сначала обрабатывается оболочкой. Оболочка выполняет подстановки псевдонимов и имя файла. После замены псевдонимов (они похожи на макросы) оболочка прерывает командную строку в список аргументов (с разделителями по пробелам). Этот список аргументов передается функции main() исполняемой команды программы как целочисленный счетчик (часто называемый argc) и указатель на NULL-конец ((void *)0) массив с nul-terminated ('\0') char массивы.

Индивидуальные команды используют свои аргументы, как бы они ни желали. Но большинство программ Unix печатает дружественное справочное сообщение, если задано аргумент -h (так как он начинается с знака минус, он называется опцией). Программное обеспечение GNU также примет вариант "long-form" --help.

Поскольку существует множество различий между различными версиями программ Unix, самым надежным способом обнаружить точный синтаксис, который требуется программе, - это спросить саму программу. Если это не говорит вам, что вам нужно (или слишком загадочно понимать), вы должны проверить локальную страницу man (man grep). А для программного обеспечения gnu часто можно получить еще больше информации от info grep.

Ответ 3

Оболочка расширяет '*.*' в список имен файлов и передает расширенный список имен файлов в программу, такую ​​как grep. Сама программа grep не расширяет имена файлов.

Итак, ответ на ваш вопрос: grep не получает 2 аргумента; оболочка преобразует '*.*' во что-то grep может понять.

GNU grep отличается от Unix grep поддержкой дополнительных параметров, таких как -w и -B и -A.

Мне кажется, что FreeBSD использует версию GNU grep:

Ответ 4

Как grep видит, что аргумент подстановки зависит от вашей оболочки. (Стандартная) У оболочки Bourne есть переключатель (-f), чтобы отключить имя файла globbing (см. справочные страницы).

Вы можете активировать этот переключатель в script с помощью

set -f