A primeira parte de seus dois comandos ( cat FILENAME
) é sempre a mesma e apenas imprime o conteúdo do arquivo especificado no fluxo STDOUT. Eu não vou explicar mais nada.
O ponto de nosso interesse é a parte grep
.
Sintaxe de grep
:
grep [OPTIONS] PATTERN [FILE...]
Você pode passar grep
algumas opções para ajustar seu comportamento (por exemplo, definir o sabor RegEx usado ou controlar a formatação de saída), mas elas não são usadas no seu caso.
O próximo argumento único deve ser o padrão a ser correspondido, em que uma expressão regular ("RegEx") ou uma sequência fixa (se grep
for chamado com a opção -F
) é obrigatória . No seu exemplo, esta é a parte install
ou "\ install\ "
. Eu explicarei no próximo parágrafo.
Depois disso, você especifica a origem dos dados para corresponder. Isso pode ser um nome de arquivo ou nada. No segundo caso, grep
lerá do fluxo STDIN (entrada padrão: normalmente o que você digita com o teclado), onde você canaliza ( |
) a saída do comando anterior.
Como passar corretamente o argumento "PATTERN"?
O parâmetro padrão deve ser um único argumento. Isso significa que você não pode simplesmente passar várias palavras ou qualquer coisa contendo espaços ou shell de caracteres especiais aqui, porque os espaços são tratados como separadores de argumentos no Bash e provavelmente todos os outros shell também, e os caracteres especiais shell como ;
irão quebrar o comando.
Mas você tem duas opções para incluir espaços no padrão para corresponder de qualquer maneira:
-
Coloque a string inteira para corresponder em aspas simples (
'...'
) ou dupla ("..."
). Dessa forma, o shell analisa toda a string entre aspas como um argumento e a passa paragrep
. -
Escape de cada espaço no padrão com uma barra invertida (
\
). Isso significa que você escreve uma barra invertida antes de cada espaço que você não quer que seja visto como separador de argumentos pelo shell. Mas observe que, se você quiser ter uma barra invertida real no padrão, também deve escapar dela, escrevendo outra barra invertida antes.
Se analisarmos agora a diferença dos seus dois exemplos de comando grep
, vemos a diferença no que correspondem:
cat /var/log/dpkg.log | grep "\ install\ "
Isso corresponde ao padrão install
. (Observe o espaço inicial e final!)
Aqui, vemos os dois métodos: aspas duplas em torno de todo o padrão e a saída de barra invertida dos espaços dentro dele. É supérfluo, para ser honesto, seria suficiente. Embora não doa, neste caso, você não deve fazer isso e decidir sobre um método. Normalmente eu recomendaria usar aspas, pois é mais fácil de ler.
cat /var/log/dpkg.log | grep install
Isso corresponde ao padrão install
. (Sem espaços ao redor.)
Aqui, o padrão consiste apenas na palavra install
, nada mais. Sem espaços.
Diferença entre seus comandos:
Como eu disse, o primeiro dos seus exemplos corresponde apenas à palavra install
quando está cercada por espaços. Não corresponderia se, e. Há um ponto final ou qualquer outro caractere diretamente antes ou depois dele. Também não corresponderia à palavra diretamente no início ou no final de uma linha.
O segundo exemplo não se preocupa com nenhum espaço antes ou depois da palavra install
. Ele também coincide nos começos e finais da linha, bem como se estiver cercado por qualquer pontuação. Corresponde mesmo se houver uma palavra contendo esta sequência de letras em qualquer lugar, por ex. "desinstalar", "reinstalar" ou "instalação" também!
Exemplo com escape de barra invertida correta / útil:
Como no exemplo que você forneceu, as barras invertidas são supérfluas, aqui o mesmo exemplo sem aspas, mas com a barra invertida escapando apenas:
cat /var/log/dpkg.log | grep \ install\
Ou se você quiser combinar a string "Eu gosto do Ubuntu" em um arquivo /home/you/path with spaces/textfile
sem usar aspas, você faria assim:
grep I\ like\ Ubuntu /home/you/path\ with\ spaces/textfile
Você verá que também deve escapar de espaços em nomes de caminho ou de arquivo ou citá-los. A linha acima é igual à linha abaixo:
grep "I like Ubuntu" "/home/you/path with spaces/textfile"