Vetores_Exemplos_1 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. Fonte https://www.monolitonimbus.com.br/shell-script-vetores/
  2. Shell Script: vetores
  3. 15 de Fevereiro de 2014 Vinicius Informática Seja o primeiro a comentar
  4. 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).
  5. 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:
  6. aeroportos=("cgh" "gru" "bsb" "sdu")
  7. 1
  8. aeroportos=("cgh" "gru" "bsb" "sdu")
  9. 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:
  10. $ echo ${aeroportos[1]}
  11. 1
  12. $ echo ${aeroportos[1]}
  13. 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:
  14. #!/bin/bash
  15. #crontab -e: [minutos] [horas] [dias do mês] [mês] [dias da semana] [usuário] [comando]
  16. #59 23 * * * receiver ./transmite.sh
  17. data=`date +%F`
  18. ano=`date +%Y`
  19. #IPs dos aeroportos estao definidos em /home/locator/.ssh/config na máquina com o script
  20. aeroportos=("cgh" "gru" "bsb" "sdu")
  21. aeroporto=("Congonhas" "Guarulhos" "Brasilia" "Santos_Dumont")
  22. LIMITE=`echo ${aeroportos[*]} | wc -w`
  23. for ((i=0; i <= $LIMITE-1 ; i++)) do # Mandar pra BACKUP no PC "ip"
  24. sshpass -p "SENHA" rsync -azvr --progress user@${aeroportos[$i]}:/home/dados/$data user@ip:/dados/${aeroporto[$i]}/BACKUP/$ano
  25. done
  26. 1
  27. 2
  28. 3
  29. 4
  30. 5
  31. 6
  32. 7
  33. 8
  34. 9
  35. 10
  36. 11
  37. 12
  38. #!/bin/bash
  39. #crontab -e: [minutos] [horas] [dias do mês] [mês] [dias da semana] [usuário] [comando]
  40. #59 23 * * * receiver ./transmite.sh
  41. data=`date +%F`
  42. ano=`date +%Y`
  43. #IPs dos aeroportos estao definidos em /home/locator/.ssh/config na máquina com o script
  44. aeroportos=("cgh" "gru" "bsb" "sdu")
  45. aeroporto=("Congonhas" "Guarulhos" "Brasilia" "Santos_Dumont")
  46. LIMITE=`echo ${aeroportos[*]} | wc -w`
  47. for ((i=0; i <= $LIMITE-1 ; i++)) do # Mandar pra BACKUP no PC "ip"
  48. sshpass -p "SENHA" rsync -azvr --progress user@${aeroportos[$i]}:/home/dados/$data user@ip:/dados/${aeroporto[$i]}/BACKUP/$ano
  49. done
  50. Para exibir o intervalo fechado de i até i+k, use:
  51. $ echo ${vetor[@]:$i:((k+1))}
  52. 1
  53. $ echo ${vetor[@]:$i:((k+1))}
  54. 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
  55. #!/bin/bash
  56. # Listar diretórios/arquivos que faltam comparando com total de arquivos
  57. aeroportos=("cgh" "gru" "bsb" "sdu")
  58. for x in "${aeroportos[@]}"; do
  59. cd /dados/$x/BACKUP
  60. for i in $(cat ../../lista_dias.txt); do
  61. total_arq=0
  62. linha_dir=""
  63. total_arq=""
  64. data=(`echo $i | tr "-" "\n"`)
  65. ano=${data[0]}
  66. linha_dir=`ls $ano | grep $i`
  67. # Se o diretorio existir...
  68. if [ -n $linha_dir ]; then
  69. total_arq=`ls $ano/$i | wc -l`
  70. echo $total_arq
  71. else
  72. echo "0"
  73. fi
  74. done > /dados/controle_$x.txt 2> /dev/null
  75. done
  76. 1
  77. 2
  78. 3
  79. 4
  80. 5
  81. 6
  82. 7
  83. 8
  84. 9
  85. 10
  86. 11
  87. 12
  88. 13
  89. 14
  90. 15
  91. 16
  92. 17
  93. 18
  94. 19
  95. 20
  96. 21
  97. #!/bin/bash
  98. # Listar diretórios/arquivos que faltam comparando com total de arquivos
  99. aeroportos=("cgh" "gru" "bsb" "sdu")
  100. for x in "${aeroportos[@]}"; do
  101. cd /dados/$x/BACKUP
  102. for i in $(cat ../../lista_dias.txt); do
  103. total_arq=0
  104. linha_dir=""
  105. total_arq=""
  106. data=(`echo $i | tr "-" "\n"`)
  107. ano=${data[0]}
  108. linha_dir=`ls $ano | grep $i`
  109. # Se o diretorio existir...
  110. if [ -n $linha_dir ]; then
  111. total_arq=`ls $ano/$i | wc -l`
  112. echo $total_arq
  113. else
  114. echo "0"
  115. fi
  116. done > /dados/controle_$x.txt 2> /dev/null
  117. done
  118. 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:
  119. copy=(${original[*]})
  120. 1
  121. copy=(${original[*]})
  122. 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.
  123. Para um script receber um vetor como argumento, ele deve ser inserido na chamada dessa rotina da seguinte forma:
  124. $ teste.sh $arg1 "Sub" $arg3 $arg4 "${vetorum[@]}" "${vetordois[@]}"
  125. 1
  126. $ teste.sh $arg1 "Sub" $arg3 $arg4 "${vetorum[@]}" "${vetordois[@]}"
  127. 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:
  128. #!/bin/bash
  129. ## Script para receber array como argumento
  130. # Recebe todos os argumentos como um único array
  131. array=( "$@" )
  132. tamanho=${#array[@]}
  133. inicio=4 # Número de elementos fora dos vetores
  134. # Guardar os primeiros elementos como variáveis
  135. hist_fim=${array[0]}
  136. tipo=${array[1]}
  137. flag_mes=${array[2]}
  138. flag_ophen=${array[3]}
  139. # Percorrer vetor para trabalhar variáveis
  140. for ((i=$inicio; i <= $tamanho-1 ; i++)); do
  141. elemento=${array[$i]}
  142. echo $elemento
  143. done
  144. 1
  145. 2
  146. 3
  147. 4
  148. 5
  149. 6
  150. 7
  151. 8
  152. 9
  153. 10
  154. 11
  155. 12
  156. 13
  157. 14
  158. 15
  159. 16
  160. 17
  161. 18
  162. 19
  163. #!/bin/bash
  164. ## Script para receber array como argumento
  165. # Recebe todos os argumentos como um único array
  166. array=( "$@" )
  167. tamanho=${#array[@]}
  168. inicio=4 # Número de elementos fora dos vetores
  169. # Guardar os primeiros elementos como variáveis
  170. hist_fim=${array[0]}
  171. tipo=${array[1]}
  172. flag_mes=${array[2]}
  173. flag_ophen=${array[3]}
  174. # Percorrer vetor para trabalhar variáveis
  175. for ((i=$inicio; i <= $tamanho-1 ; i++)); do
  176. elemento=${array[$i]}
  177. echo $elemento
  178. done
  179. 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):
  180. #!/bin/bash
  181. ano=2009
  182. mes=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12")
  183. 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")
  184. 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")
  185. # para cada arquivo tar
  186. for ((m=3; m <= 11 ; m++))
  187. do
  188. arquivotar="$ano-"${mes[$m]}"_arquivos.tar.gz"
  189. #arquivotar="$ano-"${mes[$m]}"_arquivos.tar.bz2"
  190. # se o arquivo existir, descompactar
  191. if test -f $arquivotar
  192. then
  193. ndir="$ano-"${mes[$m]}""
  194. mkdir $ndir
  195. tar -zxvf $arquivotar #descompacta gz
  196. #tar -jxvf $arquivotar # descompacta bz2
  197. # para cada pasta aberta (ou seja, para cada dia)...
  198. for ((i=0; i <= 30 ; i++))
  199. do
  200. diretorio="$ano-"${mes[$m]}"-"${dia[$i]}""
  201. arq="$ano-"${mes[$m]}"-"${dia[$i]}".dat"
  202. # se o diretorio existir
  203. if test -d $diretorio
  204. then
  205. # para cada arquivo de 15 min
  206. 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
  207. done
  208. # apagar pasta do dia
  209. rm -rf $diretorio
  210. # compactar arquivo
  211. gzip $ndir/$arq
  212. fi
  213. done
  214. # mover a pasta para dados
  215. mv $ndir ../../dados
  216. fi
  217. done
  218. 1
  219. 2
  220. 3
  221. 4
  222. 5
  223. 6
  224. 7
  225. 8
  226. 9
  227. 10
  228. 11
  229. 12
  230. 13
  231. 14
  232. 15
  233. 16
  234. 17
  235. 18
  236. 19
  237. 20
  238. 21
  239. 22
  240. 23
  241. 24
  242. 25
  243. 26
  244. 27
  245. 28
  246. 29
  247. 30
  248. 31
  249. 32
  250. 33
  251. 34
  252. 35
  253. 36
  254. 37
  255. 38
  256. 39
  257. #!/bin/bash
  258. ano=2009
  259. mes=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12")
  260. 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")
  261. 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")
  262. # para cada arquivo tar
  263. for ((m=3; m <= 11 ; m++))
  264. do
  265. arquivotar="$ano-"${mes[$m]}"_arquivos.tar.gz"
  266. #arquivotar="$ano-"${mes[$m]}"_arquivos.tar.bz2"
  267. # se o arquivo existir, descompactar
  268. if test -f $arquivotar
  269. then
  270. ndir="$ano-"${mes[$m]}""
  271. mkdir $ndir
  272. tar -zxvf $arquivotar #descompacta gz
  273. #tar -jxvf $arquivotar # descompacta bz2
  274. # para cada pasta aberta (ou seja, para cada dia)...
  275. for ((i=0; i <= 30 ; i++))
  276. do
  277. diretorio="$ano-"${mes[$m]}"-"${dia[$i]}""
  278. arq="$ano-"${mes[$m]}"-"${dia[$i]}".dat"
  279. # se o diretorio existir
  280. if test -d $diretorio
  281. then
  282. # para cada arquivo de 15 min
  283. 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
  284. done
  285. # apagar pasta do dia
  286. rm -rf $diretorio
  287. # compactar arquivo
  288. gzip $ndir/$arq
  289. fi
  290. done
  291. # mover a pasta para dados
  292. mv $ndir ../../dados
  293. fi
  294. done
  295. Fontes: Viva o Linux – Brincando com vetores e Stack Overflow.