pepa
pepa

Reputation: 11

how to direct a sh script to run a python script?

I wrote a python script that calls two files to perform some calculations and asks for a name for the new file to place the calculation in so my code runs like this:

python code.py in_file1 in_file2 outfile

Now, I have several files that need the same calculation and their names only change by the last numbers, so I wanted to do a script that takes the different needed files in a folder performs the python script and name the outputs changing only the las number according to the given in_file1 (infield_2 actually does not change).

I tried something simple but is not working

#!/bin/bash
python code.py in_file[19]* infile_2 outfile[19]*

I get an error from the usage of python saying that usage: python code.py [-h] in in2 out unrecognized arguments

I know for sure that code.py works, I just wanted to spare to do it one file at a time. Thank you. I am really new in python and linux, appreciate any help you can give.

Upvotes: 0

Views: 167

Answers (3)

tripleee
tripleee

Reputation: 189357

The shell simply expands the wildcard in_file[19]* there and then into list of all matching files. There is no loop here. If you want a loop, you will need an explicit loop, something like

#!/bin/bash
for file in in_file[19]*; do
    python code.py "$file" infile_2 "out${file#in}"
done

where the variable file gets assigned to each matching file in turn, and the variable substitution ${var#prefix} expands to the value of var with any string prefix removed from the beginning.

Incidentally, the python is redundant if you make code.py executable, and ensure it has a correct shebang line.

Note also that [19] matches a single character, so your wildcard matches any files whose name starts with in_file1 or in_file9 but no others. I'm speculating maybe that's not what you mean.

Upvotes: 1

ForceBru
ForceBru

Reputation: 44838

You can do the same in Python

from subprocess import call

fname="in_file{} infile2 outfile{}"
for x in xrange(1,11):
    d=call(["python","code.py",fname.format(x,x)])
    if d:
        print "Error executing: {}".format(d)

If you execute the following

fname="in_file{}"
for x in xrange(1,11):
    print ["python","code.py",fname.format(x)]

It will print the following

['python', 'code.py', 'in_file1']
['python', 'code.py', 'in_file2']
['python', 'code.py', 'in_file3']
['python', 'code.py', 'in_file4']
['python', 'code.py', 'in_file5']
['python', 'code.py', 'in_file6']
['python', 'code.py', 'in_file7']
['python', 'code.py', 'in_file8']
['python', 'code.py', 'in_file9']
['python', 'code.py', 'in_file10']

Upvotes: 1

A.J. Uppal
A.J. Uppal

Reputation: 19264

You can do this in :

import os

name = "in_file%d"
for i in range(1, 21):
    os.system("python code.py in_file{} in_file2 outfile{}".format(i, i))

This works as the following, with the os library calling the outputted strings:

>>> for i in range(1, 21):
...     "python code.py in_file{} in_file2 outfile{}".format(i, i)
... 
'python code.py in_file1 in_file2 outfile1'
'python code.py in_file2 in_file2 outfile2'
'python code.py in_file3 in_file2 outfile3'
'python code.py in_file4 in_file2 outfile4'
'python code.py in_file5 in_file2 outfile5'
'python code.py in_file6 in_file2 outfile6'
'python code.py in_file7 in_file2 outfile7'
'python code.py in_file8 in_file2 outfile8'
'python code.py in_file9 in_file2 outfile9'
'python code.py in_file10 in_file2 outfile10'
'python code.py in_file11 in_file2 outfile11'
'python code.py in_file12 in_file2 outfile12'
'python code.py in_file13 in_file2 outfile13'
'python code.py in_file14 in_file2 outfile14'
'python code.py in_file15 in_file2 outfile15'
'python code.py in_file16 in_file2 outfile16'
'python code.py in_file17 in_file2 outfile17'
'python code.py in_file18 in_file2 outfile18'
'python code.py in_file19 in_file2 outfile19'
'python code.py in_file20 in_file2 outfile20'
>>> 

Upvotes: 0

Related Questions