Eu preciso escrever um script que inicie meu programa com argumentos diferentes, mas eu'sou novo no Bash. Eu começo o meu programa com:
./MeuPrograma.exe Dados/dados1.txt [Logs/dados1_Log.txt]
.
Aqui está o pseudo-código do que eu quero fazer:
for each filename in /Data do
for int i = 0, i = 3, i++
./MyProgram.exe Data/filename.txt Logs/filename_Log{i}.txt
end for
end for
Então I'm realmente intrigado como criar um segundo argumento a partir do primeiro, então parece que o dataABCD_Log1.txt e iniciar o meu programa.
Algumas notas primeiro: quando você utiliza Data/data1.txt
como argumento, deveria ser realmente /Data1.txt
(com uma barra principal)? Além disso, o laço externo deve procurar apenas por arquivos .txt, ou todos os arquivos em /Data? Aqui's uma resposta, assumindo /Data/data1.txt
e arquivos .txt apenas:
#!/bin/bash
for filename in /Data/*.txt; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
done
done
Notas:
/Data/*.txt
se expande para os caminhos dos arquivos de texto em /Data (incluindo o /Data/ part)$( ... )
executa um comando shell e insere sua saída nesse ponto na linha de comandobasename somepath .txt
produz a parte base do somepath, com .txt removido do final (por exemplo /Data/file.txt
-> file
)Se você precisava executar MyProgram com Data/file.txt
em vez de /Data/file.txt
, utilize "${filename#/}"
para remover a barra principal. Por outro lado, se ele's realmente Data
e não /Data
você quer escanear, use for filename in Data/*.txt
.
Desculpe por necromanciar o fio, mas sempre que você itera por cima de arquivos através do globbing, é's uma boa prática para evitar o caso de canto onde o glob não combina (o que faz com que a variável de laço se expanda para a própria cadeia de padrão do glob (que não combina)).
Por exemplo:
for filename in Data/*.txt; do
[ -e "$filename" ] || continue
# ... rest of the loop body
done
Referência: Bash Pitfalls
for file in Data/*.txt
do
for ((i = 0; i < 3; i++))
do
name=${file##*/}
base=${name%.txt}
./MyProgram.exe "$file" Logs/"${base}_Log$i.txt"
done
done
A substituição name=${file##**/}
(expansão do parâmetro da shell) remove o caminho principal até a última /
.
A substituição base=${nome%.txt}
remove o .txt
móvel. It'é um pouco mais complicado se as extensões podem variar.