Функциональность идентична, кроме движка регулярных выражений; имеет смысл поделиться кодом, либо создав библиотеку (более распространенный подход в наши дни), либо используя один двоичный файл, который проверяет его имя (argv[0]
), чтобы определить, какое поведение запрашивается. (Третья возможность состоит в том, чтобы иметь одно имя и использовать опции для выбора различных поведений, конечно. Это то, что делают команды, такие как git
и tar
; одна команда - это «интерфейс», но вы получаете совершенно разные поведения при указание различных действий.)
Причиной существования различных команд является долгое наследие, восходящее к ранним временам Unix. Обычная старая версия grep
была одной из самых ранних реализаций регулярных выражений, и по мере улучшения понимания разработчиками этой конкретной проблемной области развивались новые инструменты с новыми возможностями. По причинам обратной совместимости эти новые функции нельзя просто интегрировать в grep
(это изменило бы его поведение), поэтому новые команды получили новые имена. К тому времени, когда POSIX приступил к стандартизации, разделение труда между grep
, egrep
и fgrep
уже было твердо установлено, хотя в ретроспективе можно утверждать, что по крайней мере один из них является избыточным.