Como colocar um script em loop em muitos arquivos?

3

Eu tenho Gnuplot roteiro (exe) , dentro desse script que eu fornecer X_001 como um arquivo de entrada para ser traçada por uma determinada função dando arquivo de saída com X_001 .png Ele funciona bem se eu colocar manualmente o nome dos arquivos de entrada e saída. Eu tentei fazer o loop desse script nos arquivos {X_001..X_300} Eu escrevi este loop

for i in X_*; do sed -i 's/X_*/${i}/g' exe ; ./exe ; done

mas isso não ajuda

isto onde a mudança no script exe deve ser feita

set term png size 1600,1200
set output "X_001.png"
splot 'X_001'
    
por Mohsen El-Tahawy 26.11.2016 / 21:43

2 respostas

7

Eu prefiro usar um script Bash e um documento aqui para conter o snippet do Gnuplot, diretamente fornecido para gnuplot . Você não quer realmente usar X_* para as entradas e X_*.png para as saídas, porque o primeiro inclui o último - ou seja, se você executar o loop uma segunda vez sem remover os arquivos PNG, você tente usá-los como dados. Então, digamos que nossos arquivos de dados são X_*.out e desejamos plotá-los para X_*.png :

#!/bin/bash
export LANG=C LC_ALL=C

for data in X_*.out ; do
    [ -r "$data" ] || continue
    png="${data%.*}.png"

    gnuplot <<END-OF-PLOT

        set term png enhanced size 1024,512
        set output "$png"

        set title "$data"
        plot "$data" u 1:2 notitle w lines

END-OF-PLOT
done

A linha export LANG=C LC_ALL=C define o código do idioma padrão C / POSIX. Isso apenas garante que, se alguém disser que seu professor / professor / TA executa o mesmo script, mas usar um idioma diferente (e preferir um local diferente do seu), ele ainda irá regenerar os mesmos gráficos.

(O problema é que algumas localidades usam . como pontos decimais, outras usam , . Evito essa ambigüidade alternando para a localidade C / POSIX, que está sempre disponível. E usa . como ponto decimal.)

Se não houver arquivos correspondentes ao padrão de glob X_*.out , por padrão, o Bash fará uma iteração sobre o corpo do loop com data tendo o valor X_*.out em si. O teste [ -r "$data" ] || continue verifica se existe um arquivo legível chamado na variável data . Se não, ele pula para a próxima iteração (o resto do corpo do loop não é executado para este valor).

Observe a atribuição png : ${data%.*} avalia o valor da variável data - aqui o nome do arquivo de dados -, exceto que tudo a partir do último . foi removido. (Se não houver . em data , nada será removido.)

Assim, no Bash, ${data%.*}.png avalia o valor de data , exceto que, se tiver um sufixo de nome de arquivo, ele será substituído por .png . Se não houver um sufixo de nome de arquivo, .png será anexado a ele.

O <<END-MARKER é usado para iniciar o documento aqui no Bash. O conteúdo, até (mas não incluindo) uma linha que começa com END-MARKER , é fornecido como entrada. No entanto, a expansão das variáveis é feita dentro desse texto, portanto, você pode usar a sintaxe $variable ou ${variable} (e outras) no documento here, e elas serão substituídas pelo conteúdo.

Observe que, diferentemente dos comandos de linha de comando do Bash, as citações em documentos do Bash aqui são mantidas. Portanto, se png tiver valor X_001.out , então set output "$png" expandirá para e o Gnuplot verá como set output "X_001.out" .

    
por 26.11.2016 / 22:51
3

Crie um script de modelo, por exemplo, exe-template . No script de modelo, use espaços reservados para o nome do arquivo de entrada e do arquivo de saída; por exemplo, use X_input para o arquivo de entrada e X_input.png para o arquivo de saída.

set term png size 1600,1200
set output "X_input.png"
splot 'X_input'

Em seguida, no loop, use sed para substituir X_input pelo nome do arquivo de dados e grave o script modificado resultante em um arquivo temporário, por exemplo exe-tmp :

for i in X_[0-9][0-9][0-9] ; do
  sed -e 's/X_input/'${i}'/g' exe-template >exe-tmp
  chmod 755 ./exe-tmp
  ./exe-tmp
done
    
por 26.11.2016 / 22:33