Obter intervalo de linhas [RESOLVIDO]

1. Obter intervalo de linhas [RESOLVIDO]

Vinicius Miqueloti
Miqueloti

(usa Lubuntu)

Enviado em 26/09/2013 - 13:41h

Olá amigos, estou com uma lógica para desenvolver no meu shellscript, e antes de partir para loops mirabolantes e soluções mais pesadas para reinventar a roda, queria saber se grep, sed, awk, a combinação destes, etc possuem a capacidade de fazer o que desejo em uma única linha.

Estou em um projeto no qual tenho feito scripts para automatizar configurações em DSLAMs e roteadores da fabricante Alcatel.

Para isto minha ideia é baixar um "running conf" (no caso da ALU, um admin display-conf) do roteador e trato as informações de que preciso fora da caixa, para depois gerar comandos a serem efetuados nela.

Vamos ao que interessa.

supondo a seguinte configuração

(conteúdo variado para cima)
vpls 21499 customer 1 create
fdb-table-size 100000
send-flush-on-failure
remote-age 300
stp
shutdown
exit
sap 1/1/5:110 create
ingress
scheduler-policy "outside"
qos 101
exit
egress
scheduler-policy "outside"
qos 101
exit
exit
sap 2/1/5:110 create
ingress
scheduler-policy "outside"
qos 101
exit
egress
scheduler-policy "outside"
qos 101
exit
exit
mesh-sdp 10026:21499 create
force-vlan-vc-forwarding
no shutdown
exit
mac-move
no shutdown
exit
no shutdown
exit
(conteúdo variado para baixo)

O que eu quero é utilizando uma pattern com a única variável que terei (2/1/5 na linha "sap 2/1/5:110 create" por exemplo) pegar todo o conteúdo entre "vpls 21499 customer 1 create" e o ultimo "exit" do exemplo

Sei da existencia de after context e before context, porém não haverá numero de linhas certos para cima e para baixo na qual preciso pegar, nem mesmo o conteúdo entre o inicio (vpls) e o fim (ultimo exit) serão identicos.

Se não tiver nada assim terei que fazer um loop por cada vpls para saber se há a porta. Mais em fim, se alguém souber, vai simplificar a minha vida e reduzir o tempo de processamento de meu script.



  


2. MELHOR RESPOSTA

Fernando
phoemur

(usa Debian)

Enviado em 30/09/2013 - 17:19h

Fiz aqui uma gambiarra deselegante também kkk


grep ^sap RJRJO_SWAG9000_info.txt | awk '/lag-1/ {print NR}' | while read INTERVALO; do sed -n "/vpls $INTERVALO/,/vpls/p" RJRJO_SWAG9000_info.txt; done
*Tudo na mesma linha

Você escolhe a variável que quer pesquisar mudando o comando awk, no exemplo usei lag-1, veja:


[phoemur@serv:teste]$grep ^sap RJRJO_SWAG9000_info.txt | awk '/lag-1/ {print NR}' | while read INTERVALO; do sed -n "/vpls $INTERVALO/,/vpls/p" RJRJO_SWAG9000_info.txt; done
vpls 2 customer 1 create
algumas linhas de conteúdo aqui
sap lag-1:2314.*
algumas linhas de conteúdo aqui
vpls 3 customer 1 create
vpls 4 customer 1 create
algumas linhas de conteúdo aqui
sap lag-1:1234.*
algumas linhas de conteúdo aqui


Agora por exemplo vou pesquisar sap 2/1/1 (troquei para 2.1.1 pra não precisar escapar), veja:


[phoemur@serv:teste]$grep ^sap RJRJO_SWAG9000_info.txt | awk '/sap 2.1.1/ {print NR}' | while read INTERVALO; do sed -n "/vpls $INTERVALO/,/vpls/p" RJRJO_SWAG9000_info.txt; done
vpls 3 customer 1 create
algumas linhas de conteúdo aqui
sap 2/1/1:4000.*
algumas linhas de conteúdo aqui
vpls 4 customer 1 create


Basicamente eu usei o número depois dos vpls para delimitar o intervalo... Vê se deu certo... Mas é uma gambiarra horrível...
Assim você não precisará dar grep em todos os conteúdos pois ele vai pegar entre um vpls e o próximo...
A única coisa é que o número do vpls tem que bater com o número do sap

3. Re: Obter intervalo de linhas [RESOLVIDO]

Alexandre Gonçalves Monteiro da Silva
alexandregms

(usa Ubuntu)

Enviado em 26/09/2013 - 17:52h

Não entendi o problema, poderia exemplificar um pouco a melhor a saída que deseja?


4. Re: Obter intervalo de linhas [RESOLVIDO]

Fernando
phoemur

(usa Debian)

Enviado em 26/09/2013 - 19:54h

Também não entendi a saída que você quer...


tac arquivo.txt | sed '/exit/,/vpls.*customer.*create/!d' | tac


Seria algo assim?


5. Re: Obter intervalo de linhas [RESOLVIDO]

Vinicius Miqueloti
Miqueloti

(usa Lubuntu)

Enviado em 30/09/2013 - 16:35h

vamos melhorar:

tenho por exemplo em um arquivo de texto:
vpls 1 customer 1 create
algumas linhas de conteúdo aqui
sap 2/1/3:2345.*
algumas linhas de conteúdo aqui
vpls 2 customer 1 create
algumas linhas de conteúdo aqui
sap lag-1:2314.*
algumas linhas de conteúdo aqui
vpls 3 customer 1 create
algumas linhas de conteúdo aqui
sap 2/1/1:4000.*
algumas linhas de conteúdo aqui
vpls 4 customer 1 create
algumas linhas de conteúdo aqui
sap lag-1:1234.*
algumas linhas de conteúdo aqui

eu apenas informando a string "sap lag-1" queria ser capaz de obter todo o conteúdo da vpls 2 até o inicio de uma próxima vpls, e da vpls 4 até o inicio de uma próxima vpls.

Isto é, queria saber se é possível pegar um conjunto de linhas informando um elemento do meio deste conjunto e obter todo este conjunto, neste caso, todas as linhas entre vpls 2 até o próximo serviço (definido por "customer 1 create") e todas as linhas entre vpls 4 e o próximo serviço.

Estou pensando em fazer um loop deste tipo:
for sap in `cat RJRJO_SWAG9000_info.txt | grep "sap lag-1" | awk '{ print $2 }'`; do cat RJRJO_SWAG9000_info.txt | grep "$sap" -B 18 -A 18; done

O problema é que usando os comandos "Before 18 lines" e "After 18 lines" fico a merce da sorte de realmente ter todo o conteúdo do qual eu necessito dentro deste intervalo, podendo pegar conteúdos a mais ou a menos.

Pessoal, arrumei uma solução "deselegante" porem paleativa para o problema.

vou usar uma regex com o grep mesmo e tratar a saída que é mais fácil.

cat RJRJO_SWAG9000_info.txt | grep -E "vpls|sap lag-1|outro conteudo|mais outro conteudo" já resolve meu problema, apesar do trabalho que vai dar mapear todos os conteúdos do qual eu realmente preciso.


6. Re: Obter intervalo de linhas [RESOLVIDO]

Vinicius Miqueloti
Miqueloti

(usa Lubuntu)

Enviado em 30/09/2013 - 17:10h

Desculpe-me o duplo post, não está dando para editar com o chromium o poest anterior (não sei pq).

Eu vou seguir a lógica aqui mesmo desta forma, o comando é para remover pontos de acesso de serviço em roteadores aqui do trampo de uma porta x, e no final ficou assim:
cat running_conf_roteador.txt | grep -E "vpls|sap $port|outro_conteudo | ... | enezimo_conteudo" | sed -r "s/vpls(.*)customer.*/configure service vpls\1/" | sed -r "s/sap(.*)create/sap\1shutdown\nno sap\1\nexit all/"

dando uma saída similar a esta (OBS: não coloquei no grep outros conteúdos para não estender muito, nem para expor minha rede né...):

configure service vpls 212108
sap 1/1/4:2108.* shutdown
no sap 1/1/4:2108.*
exit all
configure service vpls 212112
sap 1/1/4:2112.* shutdown
no sap 1/1/4:2112.*
exit all
configure service vpls 212113
sap 1/1/4:2113.* shutdown
no sap 1/1/4:2113.*
exit all
configure service vpls 212123
sap 1/1/4:2123.* shutdown
no sap 1/1/4:2123.*
exit all
configure service vpls 212125
sap 1/1/4:2125.* shutdown
no sap 1/1/4:2125.*
exit all
configure service vpls 212154
sap 1/1/4:2154.* shutdown
no sap 1/1/4:2154.*
exit all
configure service vpls 212155
sap 1/1/4:2155.* shutdown
no sap 1/1/4:2155.*
exit all
sap 1/1/4:2158.* shutdown
no sap 1/1/4:2158.*
exit all
configure service vpls 212163
sap 1/1/4:2163.* shutdown
no sap 1/1/4:2163.*
exit all
configure service vpls 212980
sap 1/1/4:2980.* shutdown
no sap 1/1/4:2980.*
exit all
configure service vpls 213000
sap 1/1/4:3000.* shutdown
no sap 1/1/4:3000.*
exit all

Agora não sei se deixo aberto o tópico para que se descubra uma forma de solucionar o problema seguindo o raciocínio da dúvida inicial, ou se fecho pois cheguei a uma solução alternativa. Alguém pode orientar?


7. Re: Obter intervalo de linhas [RESOLVIDO]

Vinicius Miqueloti
Miqueloti

(usa Lubuntu)

Enviado em 30/09/2013 - 17:58h

Valeu phoemur, além de ter solucionado melhor do que eu o problema, aprendi mais um pouquinho de sed e awk vendo em funcionamento parâmetros que ainda não tinha utilizado!!!

Um abraço a todos que colaboraram com minha duvida ai!!! Resolvido!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts