Como iterar através de uma matriz de números no shell script?

1

Estou tentando iterar por meio de uma matriz criada após a execução de algum comando. O código usado é:

#!/bin/bash
mailx -H|grep '^ [UN]'>ListOfMessages.txt
msgNumbers='cut -c 4-5 ListOfMessages.txt'
echo $msgNumbers
for msg in "${msgNumbers[@]}";
do
echo $msg;
echo $msg|mailx;
done

O ListOfMessages.txt se parece com:

 U  5 Sender1    Thu Aug 23 14:28  179/10454 Incident
 U  7 Sender2    Thu Aug 23 15:20  179/10456 Incident
 U  8 Sender3    Thu Aug 23 15:41  192/10801 Incident
 N  9 Sender4    Thu Aug 23 15:45  197/11011 Incident

A matriz está sendo atualizada com os números 5 7 8 9, conforme necessário. Eu continuo recebendo o erro "Bad Substitution" (na linha onde o loop for iniciado).

Por favor me avise sobre o she-bang a ser usado.

    
por Devjith 23.08.2018 / 09:13

4 respostas

2

Tanto quanto eu posso ver, você não tem nenhum array no seu código. A variável msgNumbers é uma string que contém a saída do seu comando cut .

Para iterar a saída de cut , use

#!/bin/bash

mailx -H | grep '^ [UN]' | cut -c 4-5 |
while read msg; do
    print 'msg = %s\s' "$msg"
done

Isso envia a saída de cut para o loop while imediatamente a seguir, através do pipe ( | ). O loop while irá iterar com msg definido para cada linha individual de saída de cut .

O cut obtém seus dados diretamente do comando grep , o que elimina a necessidade de armazenar os dados em um arquivo intermediário.

Eu removi o comando echo $msg|mailx; porque não fazia muito sentido para mim (o utilitário mailx precisa de um endereço para enviar os dados).

O grep + cut também pode ser substituído por uma única chamada para awk , onde permitimos que awk faça o trabalho de ambas as ferramentas e imprima a segunda coluna delimitada por espaços em branco quando a expressão regular corresponder a:

#!/bin/bash

mailx -H | awk '/^ [UN]/ { print $2 }' |
while read msg; do
    print 'msg = %s\s' "$msg"
done

Não estou comentando mais sobre o uso de mailx , pois é um utilitário não padrão que é implementado de forma ligeiramente diferente nos sistemas Unix (por exemplo, minha versão não possui a opção -H ).

A linha #! parece ok para mim, se você quiser que o script seja executado por bash e se o executável bash estiver localizado nesse caminho (que normalmente está nos sistemas Linux, por exemplo, mas verifique com command -v bash em seu sistema para ter certeza). O código que eu postei acima é compatível com /bin/sh , então bash não é realmente necessário para executá-lo (seria executado em qualquer shell sh -like).

Apenas certifique-se de que o script seja executável e que você o execute sem especificar um intérprete explícito.

    
por 23.08.2018 / 09:20
0

Não faça aspas duplas na referência msgNumbers, e msgNumbers não é uma matriz, então a indexação é inútil.

    
por 23.08.2018 / 09:17
0

Use () para armazenar o valor como uma matriz.

msgNumbers=('cut -c 4-5 ListOfMessages.txt')
echo "${msgNumbers[@]}"
for msg in "${msgNumbers[@]}";
do
echo $msg;
done
    
por 23.08.2018 / 09:22
0

A questão está resolvida. O problema era que o msgNumbers não era um array indexado. Então eu mudei o for msg in "${msgNumbers[@]}"; para for msg in ${msgNumbers}; . Agora está funcionando. O resto do código é o mesmo da minha pergunta.

    
por 23.08.2018 / 10:56