Alguém pode me dizer as diferenças técnicas entre grep
, egrep
, e fgrep
e fornecem exemplos adequados?
Quando preciso usar grep
o egrep
contrário e vice-versa?
Alguém pode me dizer as diferenças técnicas entre grep
, egrep
, e fgrep
e fornecem exemplos adequados?
Quando preciso usar grep
o egrep
contrário e vice-versa?
Respostas:
Historicamente, essas opções eram fornecidas em binários separados. Em alguns sistemas Unix realmente antigos, você encontrará que precisa chamar os binários separados, mas em todos os sistemas modernos as opções são preferidas. A página de manual do grep tem detalhes sobre isso.
Quanto ao que eles fazem, -E
alterna grep para um modo especial para que a expressão seja avaliada como uma ERE (Extended Regular Expression), em oposição à sua correspondência normal de padrões. Detalhes dessa sintaxe estão na página de manual.
-E, --extended-regexp
Interpretar PATTERN como uma expressão regular estendida
A -F
opção alterna grep para um modo diferente, onde aceita um padrão para corresponder, mas depois divide esse padrão em uma sequência de pesquisa por linha e faz uma pesquisa OR em qualquer uma das strings sem fazer nenhuma correspondência especial de padrões.
-F, --fixed-strings
Interprete PATTERN como uma lista de cadeias fixas, separadas por novas linhas, qualquer uma das quais deve ser correspondida.
Aqui estão alguns exemplos de cenários:
Você tem um arquivo com uma lista de, digamos, dez nomes de usuário Unix em texto simples. Você deseja pesquisar o arquivo de grupo em sua máquina para ver se algum dos dez usuários listados está em algum grupo especial:
grep -F -f user_list.txt /etc/group
A razão pela qual a -F
opção ajuda aqui é que os nomes de usuário no seu arquivo de padrão são interpretados como cadeias de texto simples. Pontos, por exemplo, seriam interpretados como pontos, e não como curingas.
Você deseja pesquisar usando uma expressão sofisticada. Por exemplo, parênteses ()
podem ser usados para indicar grupos |
usados como um operador OR. Você pode executar esta pesquisa usando -E
:
grep -E '^no(fork|group)' /etc/group
... para retornar linhas que começam com "nofork" ou "nogroup". Sem a -E
opção, você teria que escapar dos caracteres especiais envolvidos, porque, com a correspondência normal de padrões, eles apenas procurariam esse padrão exato;
grep '^no\(fork\|group\)' /etc/group
egrep
ou fgrep
; -E
e -F
são padrão. Na verdade, existem pequenas incompatibilidades egrep
: trata de maneira {
um pouco diferente.
fgrep
usa o back-end Aho-Corasick, enquanto grep
usa uma versão modificada do Commentz-Walter. Isso significa que grep
tem uma pior complexidade O (mn), enquanto que, fgrep
na pior das hipóteses, O (m + n).
egrep
e grep -E
eram executados por diferentes executáveis, BusyBox e BSD grep. As duas variantes apresentaram diferenças comportamentais para construções não regix Posix, como \s
. Isso levou a muita confusão ...
De man grep
:
egrep é o mesmo que grep -E. fgrep é o mesmo que grep -F. Chamada direta como egrep ou O fgrep está obsoleto, mas é fornecido para permitir aplicativos históricos que confiam neles para executar sem modificações.
Você usa fgrep
ou grep -F
se não deseja que a sequência grepped seja interpretada como um padrão.
Você usa egrep
ou grep -E
se precisa usar uma regexp estendida.
egrep
e fgrep
são basicamente equivalente a grep -E
e grep -F
(respectivamente):
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (ERE, see
below). (-E is specified by POSIX.)
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by
newlines, any of which is to be matched. (-F is specified by
POSIX.)
As mensagens de erro podem ser diferentes.
De "man grep":
três programas variantes egrep, fgrep e rgrep estão disponíveis. egrep é o mesmo que grep -E. fgrep é o mesmo que grep -F. rgrep é o mesmo que grep -r. A chamada direta como egrep ou fgrep foi descontinuada, mas é fornecida para permitir que aplicativos históricos que dependem deles sejam executados sem modificação.
Se você procurar uma string literal e quiser ter certeza de que a string que você passou é interpretada literalmente (ou seja, sem correr o risco de dizer que um ponto ou ponto de interrogação será interpretado como outra coisa), use fgrep ou egrep -F.
Quanto à diferença entre egrep e grep, acho que o egrep é na maioria das vezes o que você deseja. O site do manual GNU lista as diferenças entre grep e egrep, que parecem estar na sintaxe: algumas coisas exigem barras, enquanto outras não. Eu acho que o egrep é mais "compatível" com o perl regexps e o javascript regexps, então é mais fácil para mim usar o egrep.
Btw. Eu realmente encorajo você a experimentar o ack - ele suporta PREGs e possui padrões mais úteis (por exemplo, colorir, pular diretórios provavelmente não o que você deseja, como .svn, capacidade de seguir links simbólicos e é um pouco mais fácil digitar ack do que grep -E).