Questão Ao usar vários itens, como limitar a saída de um item para a primeira instância?


Eu tenho um multi-part grep no lugar que está extraindo linhas de arquivos de configuração do roteador. O grep puxa uma variedade de campos que ocorrem apenas uma vez no arquivo, como endereço IP, status de log, comunidade snmp, etc. Para isso, eu tenho um grep simples como o seguinte:

grep -e "ip address" -e "logging status" -e "snmp community" $file

No entanto, eu também preciso puxar a primeira instância de um campo que ocorre várias vezes no arquivo, nesse caso, o campo "área ospf". Com um único grep, eu posso fazer isso via:

grep -m 1 "ospf area" $file

Como posso executar as duas funções em um único grep? Estou circulando centenas de arquivos muito longos e gostaria de manter isso o mais eficiente possível. Eu também não sou casado com grep para isso, então eu estaria interessado em ver outras idéias.


0


origem




Respostas:


Possivelmente awk seria uma ferramenta melhor para isso. Podemos nos lembrar quais imprimimos e não imprimi-los novamente com algo como:

awk '/ip address/ {print} /logging status/ {print} /snmp community/ {print} /ospf area/ {if(!ospf[$0]++) {print}}' "$file"

que irá imprimir todas as linhas que coincidam com qualquer um dos seus primeiros exemplos de grep (e cada um é feito separadamente no caso de você querer apenas o primeiro, caso contrário você pode combiná-los com |). Para linhas correspondentes ospf area nós construímos uma matriz de todas as linhas que já vimos e apenas a imprimimos se não vimos essa linha antes.

Isto irá imprimir cada original ospf area linha como escrito. Se você quer apenas o primeiro ospf area linha e não quaisquer outros que você poderia apenas mudar a configuração da matriz para definir um int / flag:

awk '/ip address|logging status|snmp community/ {print} /ospf area/ {if(!ospf++) {print}}' "$file"

e se você não quer lidar com nada diferente sobre as outras linhas, podemos simplificar usando o fato de que awkA ação padrão é imprimir a linha correspondente:

awk '/ospf area/ {if(!ospf++) {print}} /ip address|logging status|snmp community/' "$file"

3