grep
é o comando cujo objetivo principal é procurar texto por um padrão (ou padrões).
Sua aplicação simplista para esta tarefa seria
grep 1.2.3.4 db
que produzirá a (s) linha (s) " IP_address Hostname
" do arquivo db
que correspondem ao padrão “ 1.2.3.4
”.
Note que eu disse linha (s) (ao invés de linha ) e combina o padrão
(em vez de conter a string ), porque há algumas dicas aqui.
- Uma é que
grep
, como eu já disse, (por padrão) procura por padrões ao invés de strings . Esses padrões são chamados de expressões regulares e há um mundo de documentação sobre eles. O fato mais importante sobre regexs para esta discussão é que um período, ".
", é um padrão que corresponde a qualquer caractere único. Então, por exemplo, o padrão ( regex )1.2.3.4
corresponderia às strings132.364
e1a2b3c4
. Estes provavelmente não são um problema no que diz respeito à colunaIP_address
, mas essas sequências podem aparecer na colunaHostname
. - Outra é que, a menos que especificado de outra forma,
grep
procura o padrão fornecido em qualquer lugar na linha . Assim, o padrão1.2.3.4
corresponderia a linhas contendo31.2.3.4
e1.2.3.42
.
Mas acredito que você fará um bom trabalho ao conseguir a linha que deseja - e apenas essa linha - com o comando
grep "^1.2.3.4[[:space:]]" db
onde
- “
^
” é outro caractere especial em expressões regulares; isso significa que esse padrão deve aparecer no início de uma linha. -
“
[[:space:]]
” representa um caractere de espaço em branco; um espaço ou uma tabulação. Se você tiver certeza de que seu arquivodb
usa apenas espaços, basta procurar um espaço; por exemplo,grep "^1.2.3.4 " db
Eles ainda encontrarão linhas que começam com 132.364
ou 1a2b3c4
.
Mas, se o seu arquivo db
estiver estruturado corretamente,
você não deve ter essas strings no início das linhas no seu arquivo db
.
Você pode impedir que " .
" corresponda a caracteres arbitrários com qualquer um dos seguintes itens:
-
grep "^1\.2\.3\.4[[:space:]]" db
-
grep "^1\.2\.3\.4 " db
-
grep -F "1.2.3.4 " db
mas os dois primeiros exigirão que você salte pelos aros do seu script
para converter 1.2.3.4
para 1\.2\.3\.4
,
e o terceiro elimina o significado especial de " ^
" (então 31.2.3.4
ainda corresponderá).
Como dito acima, todos esses comandos correspondem a toda a linha do arquivo db
que corresponde ao endereço IP. Para obter apenas o nome do host (a segunda coluna), use
grep "^1.2.3.4[[:space:]]" db | awk '{print $2}'
Isso apenas escreverá o nome do host na saída padrão (normalmente, a tela). Uma operação mais útil em um script seria
db_host=$(grep "^1.2.3.4[[:space:]]" db | awk '{print $2}')
que captura essa saída na variável do shell db_host
.
Então, finalmente, esta seção do seu script pode parecer algo como
db_host=$(grep "^$this_IP_address[[:space:]]" db | awk '{print $2}') if [ "$db_host" = "" ] then Use the host command. ︙ fi
que você colocaria em um loop,
em que a variável this_IP_address
aceita cada endereço IP que você deseja processar.
Se você os tiver em um arquivo (ou seja, outro arquivo, separado de db
),
então leia esse arquivo uma linha de cada vez.
Por exemplo, se você tiver endereços IP (um por linha) em um arquivo chamado src_ip
,
e tudo que você quer fazer é escrever os nomes de host para a saída padrão, você poderia dizer,
while read this_IP_address do db_host=$(grep "^$this_IP_address[[:space:]]" db | awk '{print $2}') if [ "$db_host" = "" ] then # Use the host command to lookup $this_IP_address. host "$this_IP_address" | head -n 1 | awk '{print $5}' else echo "$db_host" fi done < src_ip
grep -f src_ip db
não seria particularmente útil para o problema que você está descrevendo
(se eu entendi corretamente) porque iria denunciar
todas as linhas em db
que correspondem a qualquer endereço IP em src_ip
- deixando você descobrir quais endereços IP não foram correspondidos.
Uma maneira mais simples de fazer isso me ocorreu:
awk -v this_one="$this_IP_address" '$1 == this_one {print $2}' db
que copia a variável do shell this_IP_address
para awk
variable this_one
e depois diz "imprima o segundo campo de qualquer linha cujo primeiro campo seja igual a this_one
".
Este é um processo, ao contrário de dois,
e elimina o problema de " .
" caracteres arbitrários correspondentes.
Envolva-o em db_host=$(…)
como antes.