Bash script para executar um código várias vezes e armazenar output em pastas diferentes

1. Bash script para executar um código várias vezes e armazenar output em pastas diferentes

Heitor da Silva
heitorgalacian

(usa Ubuntu)

Enviado em 23/05/2020 - 17:50h

Opa, pessoal!
Sou iniciante em programação. Estou tentando criar um bash script para rodar um código várias vezes (simulação numérica de um sistema físico). O código em questão recebe alguns parâmetros que são informados na linha de comando da seguinte forma:

./code-name --parametro1=...  parametro2=...  parametro3=...   


No meu caso, estarei recebendo tais parâmetros de uma tabela criada no Mathematica importada num arquivo data.txt onde cada linha corresponde a um conjunto dos parâmetros, ou seja, {parametro1,parametro2,parametro3}. Supondo que meu arquivo data.txt possua j linhas, tentei escrever um bash script mas não sei se está correto. A tentativa é a seguinte:

#! /bin/bash
echo "Programa a ser executado: "
read file
echo "Numero de dados a ser analisado: "
read j
for (( i=1 ; i<=$j, i++))
do
./file --parametro1=data.txt[[i,1]] --parametro2=data.txt[[i,2]] --parametro3=data.txt[i,3]]
done


Ao executar o script, recebo a seguinte mensagem de erro:
./simulation.sh: line 4: syntax error: arithmetic expression required
./simulation.sh: line 4: syntax error: `(( i=1 ; i<=$j, i++))'


Além disso, eu também gostaria de salvar o output gerado de cada uma das j execuções em uma pasta diferente mas não tenho ideia de como implementar isso no meu script.


  


2. Re: Bash script para executar um código várias vezes e armazenar output em pastas diferentes

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 23/05/2020 - 20:42h

heitorgalacian escreveu:

Opa, pessoal!
Sou iniciante em programação. Estou tentando criar um bash script para rodar um código várias vezes (simulação numérica de um sistema físico). O código em questão recebe alguns parâmetros que são informados na linha de comando da seguinte forma:

./code-name --parametro1=...  parametro2=...  parametro3=...   


No meu caso, estarei recebendo tais parâmetros de uma tabela criada no Mathematica importada num arquivo data.txt onde cada linha corresponde a um conjunto dos parâmetros, ou seja, {parametro1,parametro2,parametro3}. Supondo que meu arquivo data.txt possua j linhas, tentei escrever um bash script mas não sei se está correto. A tentativa é a seguinte:

#! /bin/bash
echo "Programa a ser executado: "
read file
echo "Numero de dados a ser analisado: "
read j
for (( i=1 ; i<=$j, i++))
do
./file --parametro1=data.txt[[i,1]] --parametro2=data.txt[[i,2]] --parametro3=data.txt[i,3]]
done


Ao executar o script, recebo a seguinte mensagem de erro:
./simulation.sh: line 4: syntax error: arithmetic expression required
./simulation.sh: line 4: syntax error: `(( i=1 ; i<=$j, i++))'


Além disso, eu também gostaria de salvar o output gerado de cada uma das j execuções em uma pasta diferente mas não tenho ideia de como implementar isso no meu script.

Boa noite Heitor, vamos por partes.....
Segue exemplo de
Como ler um arquivo, linha a linha,
pegar cada campo e gerar um array...

n=0;
while read line;do
let n++;
IFS="," read -a cps <<< "${line//[\{\}]}";
echo "Linha nº $n ${cps[0]} ${cps[1]} ${cps[2]}"; done<dados.txt
Linha nº 1 Param_91 Param_72 Param_85
Linha nº 2 Param_28 Param_11 Param_36
Linha nº 3 Param_68 Param_52 Param_32
Linha nº 4 Param_8 Param_45 Param_37
Linha nº 5 Param_43 Param_23 Param_37
Linha nº 6 Param_2 Param_59 Param_49
Linha nº 7 Param_69 Param_94 Param_67
Linha nº 8 Param_73 Param_43 Param_17
Linha nº 9 Param_8 Param_18 Param_12
Linha nº 10 Param_32 Param_93 Param_51
Linha nº 11 Param_61 Param_78 Param_89
Linha nº 12 Param_90 Param_85 Param_30
Linha nº 13 Param_4 Param_51 Param_39
Linha nº 14 Param_91 Param_55 Param_20
Linha nº 15 Param_35 Param_99 Param_47
Linha nº 16 Param_32 Param_41 Param_99
Linha nº 17 Param_17 Param_3 Param_97
Linha nº 18 Param_64 Param_33 Param_35
Linha nº 19 Param_53 Param_53 Param_7
Linha nº 20 Param_95 Param_96 Param_67


O seu arquivo data.txt é no formato Json?
______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________


3. Re: Bash script para executar um código várias vezes e armazenar output em pastas diferentes

Heitor da Silva
heitorgalacian

(usa Ubuntu)

Enviado em 24/05/2020 - 14:05h

Boa tarde, Marcelo!

Agradeço sua resposta. Neste meio tempo, eu estive fuçando na internet, mexendo e mexendo no script até chegar a algo que tem funcionado. Dê uma olhada:

#! /bin/bash
parameterfile='data.csv'
execname='twolevelcore'
j=1
while IFS="," read p1 p2 p3 p4 p5
do
mkdir -p sim$j
mv $execname sim$j
cd sim$j
./$execname --dtone=$p1 --wobar=$p2 --Lambda=$p3 --prefactor=$p4 --tempototal=$p5
mv $execname ../
echo $p1,$p2,$p3,$p4,$p5 >> "parameters.txt"
cd ..
python3 dprof.py sim$j
python3 densityprofiles_comparisons.py sim$j
j=$((j+1))
done < $parameterfile


Então como você pode ver, meus parâmetros estão armazenados neste arquivo data.csv, uma tabela que gero no Mathematica. A j-ésima execução cria a pasta simj, leva o arquivo executável execname para dentro dela, executa com os parâmetros de data.csv e também alguns plots que preciso que são feitos pelos arquivos .py dprof e densityprofiles_comparisons. Ao final de cada execução, o executável é removido da pasta simj e o loop prossegue para j+1 criando a pasta sim(j+1) e assim por diante.

Gostaria de saber como eu poderia adicionar um cronômetro nesse script pois seria interessante saber o tempo total decorrido para rodar todas as simulações. Você teria alguma ideia de como fazê-lo?


4. Re: Bash script para executar um código várias vezes e armazenar output em pastas diferentes

mau blau
blaublau22

(usa GoblinX)

Enviado em 24/05/2020 - 15:18h

erro neste loop aritmético:
for (( i=1 ; i<=$j, i++)) 


for (( i=1 ; i<=j ; i++)) 


variável j não precisa do $, opcional
e confundiu vírgula com ponto e vírgula

cronômetro simples:
versões mais recentes do bash atualizam a variável $SECONDS uma vez por segundo, então, ao final do script ou no meio do loop, você pode imprimir ela ou quem sabe calcular o delta...

se vc for usar para cálculos, recomendo o z shell, aritmética muito boa com números de ponto flutuante, mas vi que tu usa progs específicos para cálculos, enfim..
o zshell tb tem a var $SECONDS mas se tu definir ela como número de ponto flutuante com 4 casas decimais, por exemplo, 'typeset -F 4 SECONDS', daí ela fica mais precisa..


5. Re: Bash script para executar um código várias vezes e armazenar output em pastas diferentes

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 24/05/2020 - 17:09h


heitorgalacian escreveu:

Boa tarde, Marcelo!

Agradeço sua resposta. Neste meio tempo, eu estive fuçando na internet, mexendo e mexendo no script até chegar a algo que tem funcionado. Dê uma olhada:

#! /bin/bash
parameterfile='data.csv'
execname='twolevelcore'
j=1
while IFS="," read p1 p2 p3 p4 p5
do
mkdir -p sim$j
mv $execname sim$j
cd sim$j
./$execname --dtone=$p1 --wobar=$p2 --Lambda=$p3 --prefactor=$p4 --tempototal=$p5
mv $execname ../
echo $p1,$p2,$p3,$p4,$p5 >> "parameters.txt"
cd ..
python3 dprof.py sim$j
python3 densityprofiles_comparisons.py sim$j
j=$((j+1))
done < $parameterfile


Então como você pode ver, meus parâmetros estão armazenados neste arquivo data.csv, uma tabela que gero no Mathematica. A j-ésima execução cria a pasta simj, leva o arquivo executável execname para dentro dela, executa com os parâmetros de data.csv e também alguns plots que preciso que são feitos pelos arquivos .py dprof e densityprofiles_comparisons. Ao final de cada execução, o executável é removido da pasta simj e o loop prossegue para j+1 criando a pasta sim(j+1) e assim por diante.

Gostaria de saber como eu poderia adicionar um cronômetro nesse script pois seria interessante saber o tempo total decorrido para rodar todas as simulações. Você teria alguma ideia de como fazê-lo?

Quanto ao cronômetro,
Use o comando time,
Exemplo:
time script.sh
Ou pode gerar uma var com o Unix Time Stamp.NanoSegundos
no inicio do script, e no final, fazer a subtração.....
ini=$(date +%s.%N)
O problema de:
while IFS="," read p1 p2 p3 p4 p5 . . . .
É , se o nº de campos for diferente de 5, vai dar erro . . .


______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts