Eu usaria o awk para fazer isso (assumindo que o ip é a primeira coluna):
awk '!seen[$1]++ && $1 ~ /123.123.123.123|124.124.124.124|125.125.125.125/' /var/log/apache2/other_vhosts_access.log
Isto:
cat /var/log/apache2/other_vhosts_access.log |grep -m 1 123.123.123.123
me dá a primeira ocorrência do IP 123.123.123.123.
Mas como obter a 1ª ocorrência de IP1 e a 1ª ocorrência de IP2 e a 1ª ocorrência de IP3 e ...?
Isso obviamente não funciona, mas dá a ideia:
cat /var/log/apache2/other_vhosts_access.log |grep -m 1 123.123.123.123 AND 124.124.124.124 AND 125.125.125.125
Eu usaria o awk para fazer isso (assumindo que o ip é a primeira coluna):
awk '!seen[$1]++ && $1 ~ /123.123.123.123|124.124.124.124|125.125.125.125/' /var/log/apache2/other_vhosts_access.log
Observe que grep '123.123.123.123'
não fornece a primeira ocorrência do 123.123.123.123
IP , mas do padrão 123.123.123.123
que corresponde a 123.123.123.123
, mas também de 1234123-123e123
como .
é o operador de expressão regular que corresponde a qualquer caractere único.
O 123\.123\.123\.123
corresponderia apenas a 123.123.123.123
, mas isso seria 23\.123\.123\.1
. Veja também a opção -F
de grep
para correspondência de cadeia fixa.
Aqui, eu faria:
awk '
!ips_seen {ip[$0]; n++; next}
{
found = 0
for (i in ip)
if (index($0, i)) {
found = 1
delete ip[i]
n--
}
}
found
!n {exit}' ips.txt ips_seen=1 input.txt
Em que ips.txt
contém a lista de endereços IP, um por linha.
Lembre-se de que, se uma linha contiver mais de um IP, ela ainda será impressa apenas uma vez.
Ao usar index()
, que apenas procura substrings, nós cuidamos do primeiro problema acima de .
correspondendo a qualquer caractere, mas não ao segundo.
Tags grep find text-processing sed