123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- Fonte https://www.monolitonimbus.com.br/shell-script-vetores/
- Shell Script: vetores
- 15 de Fevereiro de 2014 Vinicius Informática Seja o primeiro a comentar
- Um array mantêm uma série de elementos de dados, geralmente do mesmo tamanho e tipo de dados. Elementos individuais são acessados por sua posição no array, cuja posição é dada por um índice (geralmente, dentro de uma sequência de números inteiros). É conhecido como vetor, caso seja uni-dimensional, ou matriz, para um array bi-dimensional. Vejamos alguns pontos importantes e exemplos de uso de vetores em shell script (utilizado interpretador de comandos compatível com o sh, que é o bash).
- Em um vetor, os elementos são separados por um espaço. Neste caso, o espaço não é um caractere (‘ ‘), e sim um separador dos elementos. Vejamos esse exemplo de vetor e o acesso às diferentes posições e elementos do vetor:
- aeroportos=("cgh" "gru" "bsb" "sdu")
- 1
-
- aeroportos=("cgh" "gru" "bsb" "sdu")
- Nesse caso, aeroportos[0] é “cgh”, aeroportos[1] é “gru” e assim por diante. Para imprimir na tela o conteúdo de uma posição do vetor, temos:
- $ echo ${aeroportos[1]}
- 1
-
- $ echo ${aeroportos[1]}
- Para exibir todos os elementos de um vetor, devemos usar a mesma estrutura, mas no lugar do índice, utilizar arroba [@] ou asterisco [*]. Veja o exemplo a seguir de uma rotina para copiar os dados de computadores em diferentes aeroportos para um computador de backup, onde cada diretório possui como nome a data do dia na forma ANO-MES-DIA:
- #!/bin/bash
- #crontab -e: [minutos] [horas] [dias do mês] [mês] [dias da semana] [usuário] [comando]
- #59 23 * * * receiver ./transmite.sh
- data=`date +%F`
- ano=`date +%Y`
- #IPs dos aeroportos estao definidos em /home/locator/.ssh/config na máquina com o script
- aeroportos=("cgh" "gru" "bsb" "sdu")
- aeroporto=("Congonhas" "Guarulhos" "Brasilia" "Santos_Dumont")
- LIMITE=`echo ${aeroportos[*]} | wc -w`
- for ((i=0; i <= $LIMITE-1 ; i++)) do # Mandar pra BACKUP no PC "ip"
- sshpass -p "SENHA" rsync -azvr --progress user@${aeroportos[$i]}:/home/dados/$data user@ip:/dados/${aeroporto[$i]}/BACKUP/$ano
- done
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
-
- #!/bin/bash
- #crontab -e: [minutos] [horas] [dias do mês] [mês] [dias da semana] [usuário] [comando]
- #59 23 * * * receiver ./transmite.sh
- data=`date +%F`
- ano=`date +%Y`
- #IPs dos aeroportos estao definidos em /home/locator/.ssh/config na máquina com o script
- aeroportos=("cgh" "gru" "bsb" "sdu")
- aeroporto=("Congonhas" "Guarulhos" "Brasilia" "Santos_Dumont")
- LIMITE=`echo ${aeroportos[*]} | wc -w`
- for ((i=0; i <= $LIMITE-1 ; i++)) do # Mandar pra BACKUP no PC "ip"
- sshpass -p "SENHA" rsync -azvr --progress user@${aeroportos[$i]}:/home/dados/$data user@ip:/dados/${aeroporto[$i]}/BACKUP/$ano
- done
- Para exibir o intervalo fechado de i até i+k, use:
- $ echo ${vetor[@]:$i:((k+1))}
- 1
-
- $ echo ${vetor[@]:$i:((k+1))}
- Outro exemplo, que conta o número de arquivos de diretórios (listados em cada linha do arquivo lista_dias.txt) e imprime o total em linhas do arquivo controle_aeroporto.txt
- #!/bin/bash
- # Listar diretórios/arquivos que faltam comparando com total de arquivos
- aeroportos=("cgh" "gru" "bsb" "sdu")
- for x in "${aeroportos[@]}"; do
- cd /dados/$x/BACKUP
- for i in $(cat ../../lista_dias.txt); do
- total_arq=0
- linha_dir=""
- total_arq=""
- data=(`echo $i | tr "-" "\n"`)
- ano=${data[0]}
- linha_dir=`ls $ano | grep $i`
- # Se o diretorio existir...
- if [ -n $linha_dir ]; then
- total_arq=`ls $ano/$i | wc -l`
- echo $total_arq
- else
- echo "0"
- fi
- done > /dados/controle_$x.txt 2> /dev/null
- done
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
-
- #!/bin/bash
- # Listar diretórios/arquivos que faltam comparando com total de arquivos
- aeroportos=("cgh" "gru" "bsb" "sdu")
- for x in "${aeroportos[@]}"; do
- cd /dados/$x/BACKUP
- for i in $(cat ../../lista_dias.txt); do
- total_arq=0
- linha_dir=""
- total_arq=""
- data=(`echo $i | tr "-" "\n"`)
- ano=${data[0]}
- linha_dir=`ls $ano | grep $i`
- # Se o diretorio existir...
- if [ -n $linha_dir ]; then
- total_arq=`ls $ano/$i | wc -l`
- echo $total_arq
- else
- echo "0"
- fi
- done > /dados/controle_$x.txt 2> /dev/null
- done
- Para copiar o vetor original para uma nova variável, não basta fazer da mesma forma que é feito com uma variável. Além de indicar que deseja copiar todos os seus elementos, deve colocar novamente parênteses para transformar o conteúdo em elementos de um novo vetor:
- copy=(${original[*]})
- 1
-
- copy=(${original[*]})
- Se não fizer isso, todos os elementos do vetor original viram uma única posição em uma variável. Uma discussão com exemplos é realizada no blog do Ahmed Amayem.
- Para um script receber um vetor como argumento, ele deve ser inserido na chamada dessa rotina da seguinte forma:
- $ teste.sh $arg1 "Sub" $arg3 $arg4 "${vetorum[@]}" "${vetordois[@]}"
- 1
-
- $ teste.sh $arg1 "Sub" $arg3 $arg4 "${vetorum[@]}" "${vetordois[@]}"
- Note que foram passados quatro variáveis e dois vetores. Para o shell script receber esses valores, não será possível receber um vetor como uma variável só. Assim, a ideia é tratar TODOS os elementos (incluindo os elementos dos vetores) como sendo um único array e depois separar as variáveis fora dos vetores. Veja o exemplo:
- #!/bin/bash
- ## Script para receber array como argumento
- # Recebe todos os argumentos como um único array
- array=( "$@" )
- tamanho=${#array[@]}
- inicio=4 # Número de elementos fora dos vetores
- # Guardar os primeiros elementos como variáveis
- hist_fim=${array[0]}
- tipo=${array[1]}
- flag_mes=${array[2]}
- flag_ophen=${array[3]}
- # Percorrer vetor para trabalhar variáveis
- for ((i=$inicio; i <= $tamanho-1 ; i++)); do
- elemento=${array[$i]}
- echo $elemento
- done
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
-
- #!/bin/bash
- ## Script para receber array como argumento
-
- # Recebe todos os argumentos como um único array
- array=( "$@" )
- tamanho=${#array[@]}
- inicio=4 # Número de elementos fora dos vetores
-
- # Guardar os primeiros elementos como variáveis
- hist_fim=${array[0]}
- tipo=${array[1]}
- flag_mes=${array[2]}
- flag_ophen=${array[3]}
-
- # Percorrer vetor para trabalhar variáveis
- for ((i=$inicio; i <= $tamanho-1 ; i++)); do
- elemento=${array[$i]}
- echo $elemento
- done
- Por último, um exemplo com uns vetores enormes de mês, dia e hora (a cada 15 minutos). Seu objetivo é descompactar arquivos “.tar.gz” (ou “.tar.bz2”) e unir os conteúdos em outro arquivo final (também apaga diretório que não será mais usado e compacta arquivo):
- #!/bin/bash
- ano=2009
- mes=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12")
- dia=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31")
- hora=("0000" "0015" "0030" "0045" "0100" "0115" "0130" "0145" "0200" "0215" "0230" "0245" "0300" "0315" "0330" "0345" "0400" "0415" "0430" "0445" "0500" "0515" "0530" "0545" "0600" "0615" "0630" "0645" "0700" "0715" "0730" "0745" "0800" "0815" "0830" "0845" "0900" "0915" "0930" "0945" "1000" "1015" "1030" "1045" "1100" "1115" "1130" "1145" "1200" "1215" "1230" "1245" "1300" "1315" "1330" "1345" "1400" "1415" "1430" "1445" "1500" "1515" "1530" "1545" "1600" "1615" "1630" "1645" "1700" "1715" "1730" "1745" "1800" "1815" "1830" "1845" "1900" "1915" "1930" "1945" "2000" "2015" "2030" "2045" "2100" "2115" "2130" "2145" "2200" "2215" "2230" "2245" "2300" "2315" "2330" "2345")
- # para cada arquivo tar
- for ((m=3; m <= 11 ; m++))
- do
- arquivotar="$ano-"${mes[$m]}"_arquivos.tar.gz"
- #arquivotar="$ano-"${mes[$m]}"_arquivos.tar.bz2"
- # se o arquivo existir, descompactar
- if test -f $arquivotar
- then
- ndir="$ano-"${mes[$m]}""
- mkdir $ndir
- tar -zxvf $arquivotar #descompacta gz
- #tar -jxvf $arquivotar # descompacta bz2
- # para cada pasta aberta (ou seja, para cada dia)...
- for ((i=0; i <= 30 ; i++))
- do
- diretorio="$ano-"${mes[$m]}"-"${dia[$i]}""
- arq="$ano-"${mes[$m]}"-"${dia[$i]}".dat"
- # se o diretorio existir
- if test -d $diretorio
- then
- # para cada arquivo de 15 min
- for ((h=0; h <= 95 ; h++)); do arquivo="$ano-"${mes[$m]}"-"${dia[$i]}"_"${hora[$h]}".dat" # se arquivo existir, concatenar o arquivo dentro do arquivo final test -f $diretorio/$arquivo && cat $diretorio/$arquivo >> $ndir/$arq
- done
- # apagar pasta do dia
- rm -rf $diretorio
- # compactar arquivo
- gzip $ndir/$arq
- fi
- done
- # mover a pasta para dados
- mv $ndir ../../dados
- fi
- done
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
-
- #!/bin/bash
- ano=2009
- mes=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12")
- dia=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31")
- hora=("0000" "0015" "0030" "0045" "0100" "0115" "0130" "0145" "0200" "0215" "0230" "0245" "0300" "0315" "0330" "0345" "0400" "0415" "0430" "0445" "0500" "0515" "0530" "0545" "0600" "0615" "0630" "0645" "0700" "0715" "0730" "0745" "0800" "0815" "0830" "0845" "0900" "0915" "0930" "0945" "1000" "1015" "1030" "1045" "1100" "1115" "1130" "1145" "1200" "1215" "1230" "1245" "1300" "1315" "1330" "1345" "1400" "1415" "1430" "1445" "1500" "1515" "1530" "1545" "1600" "1615" "1630" "1645" "1700" "1715" "1730" "1745" "1800" "1815" "1830" "1845" "1900" "1915" "1930" "1945" "2000" "2015" "2030" "2045" "2100" "2115" "2130" "2145" "2200" "2215" "2230" "2245" "2300" "2315" "2330" "2345")
- # para cada arquivo tar
- for ((m=3; m <= 11 ; m++))
- do
- arquivotar="$ano-"${mes[$m]}"_arquivos.tar.gz"
- #arquivotar="$ano-"${mes[$m]}"_arquivos.tar.bz2"
- # se o arquivo existir, descompactar
- if test -f $arquivotar
- then
- ndir="$ano-"${mes[$m]}""
- mkdir $ndir
- tar -zxvf $arquivotar #descompacta gz
- #tar -jxvf $arquivotar # descompacta bz2
- # para cada pasta aberta (ou seja, para cada dia)...
- for ((i=0; i <= 30 ; i++))
- do
- diretorio="$ano-"${mes[$m]}"-"${dia[$i]}""
- arq="$ano-"${mes[$m]}"-"${dia[$i]}".dat"
- # se o diretorio existir
- if test -d $diretorio
- then
- # para cada arquivo de 15 min
- for ((h=0; h <= 95 ; h++)); do arquivo="$ano-"${mes[$m]}"-"${dia[$i]}"_"${hora[$h]}".dat" # se arquivo existir, concatenar o arquivo dentro do arquivo final test -f $diretorio/$arquivo && cat $diretorio/$arquivo >> $ndir/$arq
- done
- # apagar pasta do dia
- rm -rf $diretorio
- # compactar arquivo
- gzip $ndir/$arq
- fi
- done
- # mover a pasta para dados
- mv $ndir ../../dados
- fi
-
- done
- Fontes: Viva o Linux – Brincando com vetores e Stack Overflow.
|