A abordagem mais simples que eu posso imaginar, assumindo que os números que você quer são sempre delimitados por @
symbols, é:
$ grep -oP '@\K\d+' file | perl -pe '$. % 4 != 0 && s/\n/./;'
192.168.10.16
192.169.10.16
192.128.10.16
192.162.10.16
Isto não numera as linhas, por isso, para adicioná-las,
$ grep -oP '@\K\d+' file | perl -pe '$. % 4 != 0 && s/\n/./;' | perl -pe 's/^/$.. /'
1. 192.168.10.16
2. 192.169.10.16
3. 192.128.10.16
4. 192.162.10.16
Explicação
-
grep -oP '@\K\d+' file
:-o
significa "imprimir apenas a parte correspondente da linha" e-P
ativa as PCRE (Perl Compatible Regular Expressions - Expressões Regulares Compatíveis com Perl) paragrep
. Isso nos permite usar o\d
para coincidir com números e, o mais importante, o\K
que significa "esqueça o que você combinou antes de mim". O\K
me permite grep para@\K10
e imprime apenas o10
porque o@
é anterior ao\K
. -
perl -pe
: leia o arquivo de entrada linha por linha, aplique o script fornecido por-e
a cada linha e, em seguida, imprima essa linha (-p
). -
'$. % 4 != 0 && s/\n/./;
:%
é o operador de módulo ,$.
é o número da linha atual do arquivo de entrada. Este código irá substituir um charatcer de nova linha (\n
) por um.
em linhas que não são divisíveis por 4. O resultado é que, como estamos alimentando uma lista de números (a saída degrep
), cada grupo de 4 números será impresso na mesma linha, pois o\n
foi convertido em.
. -
perl -pe 's/^/$.. /'
: Basta adicionar o número da linha atual ao início de cada linha.
Steeldriver sugeriu uma alternativa muito boa:
grep -oP '@\K\d+' file | xargs -n4 printf '%d.%d.%d.%d\n' | cat -n
O que me fez pensar sobre isso:
printf '%d.%d.%d.%d\n' $(grep -oP '@\K\d+' file ) | cat -n
Se você gosta, você pode fazer tudo em Perl e evitar pipes, mas eu usaria o método acima. De qualquer forma, sempre assumindo que seus números estão cercados por @
, isso também funcionará:
perl -ne 'push @f,(/@(\d+)@/g);
END{
$k=1;
for($i=0;$i<=$#f;$i+=4){
print "$k. " . join(".",@f[$i..($i+3)]) . "\n"; $k++}
}' file
Você pode colar isso diretamente no seu terminal, apenas altere file
para o nome real do arquivo. A saída é assim:
1. 192.168.10.16
2. 192.169.10.16
3. 192.128.10.16
4. 192.162.10.16
Explicação
-
perl -ne
: leia o arquivo de entrada linha a linha (-n
) e aplique o script fornecido por-e
. -
push @f,(/@(\d+)@/g);
: salve cada número cercado por@
como um elemento da matriz@f
. -
END{}
: faça isso depois de terminar o processamento de todas as linhas -
for($i=0;$i<=$#f;$i+=4){}
: iterar pelo array. Como os IPs têm 4 conjuntos de números, lemos o array em saltos de quatro. -
join(".",@f[$i..($i+3)])
: conecta os 4 elementos da matriz com.
para impressão. - O
$k
é apenas para imprimir os números na frente dos IPs.