Usando vários comandos com substituição de comando para preencher uma matriz ruim?

0

Estou escrevendo um script bash para "centralizar" e facilitar a busca de informações para nossos funcionários menos experientes usarem ao fornecer suporte técnico.

Quão realisticamente aceitável é este código do ponto de vista mais estrito do roteirista de Bash? Este é essencialmente o script inteiro em poucas palavras (na verdade, um shell bash, ha ha.)

#!/bin/bash

declare -a array
array=('grep -w foo /var/log/bar.log  | awk '{print $1,$2,$3,$14,$16}' | sed 's/<//g; s/>,//g; s/>//g;' | tr [:blank:] , && ssh XXX.XXX.XXX.XXX 'grep -w foo /var/log/bar.log' | awk '{print $1,$2,$3,$14,$16}' | sed 's/<//g; s/>,//g; s/>//g;' | tr [:blank:] ,')

O script continua a operar na matriz. A razão pela qual estou executando isso é porque gostaria que tudo fosse mantido na RAM, o que eu posso elaborar se necessário.

Eu sei que o código é bem feio, mas existe alguma maneira mais clara de que isso possa ser feito sem mudar meu objetivo, a linguagem de programação ou adicionar linhas de código adicionais? Eu sei que posso limpar o regexp do sed mas, além disso, atualmente não consigo pensar em nada melhor ...

    
por Nate.sh 29.09.2017 / 20:48

1 resposta

0

Sim, possivelmente, às vezes ... Depende.

Desculpe por esta resposta desconexa. A questão não menciona o propósito e o uso da matriz, nem o conteúdo do arquivo de dados, por isso é difícil dizer algo específico.

Resumo: não, essa não é a maneira usual / idiomática de trabalhar com dados em um script de shell.

O código, como está escrito, é difícil de seguir, pois é uma linha bastante longa. Parece que a maioria das operações pode ser executada por um único script awk (não gravarei este script hoje). Isso falharia no meu código de revisão, receio.

Apenas o fato de que você está tentando colocar (potencialmente) muitos dados em uma matriz me diz que você fará o processamento desta matriz em um ou mais loops de shell depois. Se for apenas um loop, por que não canalizar o resultado diretamente no loop?

Bem, veja " Por que usar um loop de shell para processar texto considerado uma prática ruim? ".

Se o pipeline de comando apenas gera poucos itens em um formato restrito (palavras únicas ou strings que de outra forma seriam bem comportadas no shell), isso ainda pode estar perfeitamente ok, mas ainda não é o modo idiomático de fazendo isso.

Os dados precisam ser lidos em algum momento, e você também pode usá-los durante a leitura, sem o problema adicional de armazená-los em uma matriz. Dependendo do que você está fazendo com os dados, isso pode ser feito por awk ou sed (ou alguma outra ferramenta) diretamente.

Tanto quanto eu posso ver, você está produzindo strings separadas por vírgula, talvez ele crie um dataset CSV com cada linha como uma entrada na matriz? Isso é perfeito para alimentar awk , por exemplo, novamente, sem armazená-lo temporariamente em uma matriz. Ou, em uma das ferramentas CSVkit para esse assunto. Você pode até mesmo passá-lo para um arquivo real e processá-lo em um ou vários outros scripts.

Para pessoas que trabalham em grandes conjuntos de dados (como eu), a leitura de arquivos em variáveis shell é impossível. Felizmente, a maioria das ferramentas padrão do Unix atua como filtros e possibilita a transmissão de dados entre estágios de um programa mais ou menos uma linha por linha, usando pipelines. A leitura de dados "na RAM" não acelera isso.

Eu quase nunca leio dados do arquivo em qualquer tipo de variável de shell. Eu uso mais frequentemente variáveis para cadeias estáticas, valores temporários de curto prazo, ou contadores e matrizes para dados estáticos, para quando uma simples substituição de parâmetro é mais fácil de executar em uma matriz do que enviar sed (como ${arr[@]%.*} para tirando a extensão de alguns nomes de arquivos em arr ) ou para agregar dados em um loop curto.

    
por 29.09.2017 / 22:35