I have several files with extensions "*.f90" in directory-A. I want to apply the following command for each file in shell script. e.g. filename.f90

f2py -h filename.pyf -m filename /path/to/directory-A/filename.f90

This will generate a ".pyf" file that I want to store in directory-B.

I am using the following script.

find "/path/to/directory-A/" -name "*.f90" -exec f2py -h {}.pyf -m {} {}.f90\;

This uses the output of find function and replaces it in the -exec command in place of "{}". which means that every where in place of "{}" my code will replace it with "filename.f90". where as I want only the file name i.e. without extension to be placed in exec command in place of "{}"

I tried using the basename command, it works in giving the filename only but "{}" in my original execute command still contains the the extension. I used following code.

find "/path/to/directory-A/" -name "*.f90" -exec basename\ {} \ .f90; -exec f2py -h {}.pyf -m {} {}.f90\;

How do I fix this issue. Also I want to execute my command in directory-B, so that the ".pyf" files are created in directory-B. how do I do this?


2 Answers 2


Use my favorite one-liner:

cd directory-A
for i in *p90; do f2py -h ${i%.p90}.pyf -m ${i%.p90} $i; mv ${i%.p90}.pyf directory-B; done

You have to understand that the "extension" is just a weird part of a file name in unix-like OSes and has no special treatment.

You may need to fiddle with quotes in the one-liner if there are spaces or other weird symbols in file names.

  • 1
    I like the % use; just note that the glob expansion will not catch any subdirectories, like find will. Not that there's a good answer to the question in the title -- thus all these workarounds.
    – Jeff Schaller
    Jun 8, 2015 at 1:54
  • You didn't mention any subdirectories in the question and it is unclear how the f2py command handles filenames, whether they can be with full path or not, so I went by the example. In case of subdirectories you will need some kind of postprocessing, either by feeding the data to a wrapper as suggested above or feeding them o another one-liner like mine: find -name *p90 | while read a; do ...some-clever-postprocessing...; f2py ...; done. Did I get it right this time? If so let me know so that I can update the answer.
    – jficz
    Jun 8, 2015 at 10:47
  • It's not my question; I just wanted to point out that the question uses find, which recurses.
    – Jeff Schaller
    Jun 8, 2015 at 10:59
  • Oh, I see, sorry about that, I was on the phone and assumed, prematurely obviously.
    – jficz
    Jun 8, 2015 at 11:28
find "/path/to/directory-A/" -name "*.f90" -exec /path/to/callf2py {} \;


f=$(basename $1)
f2py -h $f.pyf -m $f.f90
  • Thanks. At "f=$(basename $1)" I get error saying permission denied. I have created a new shell script with this code and I am calling this code callf2py from the original code. Permission for all the files are okay.
    – Syed Moez
    Jun 7, 2015 at 22:26
  • post your command, the script you created, and the output. the answer works fine for me.
    – Jeff Schaller
    Jun 8, 2015 at 0:56
  • I have created a shell script callf2py.sh which has the following code: #!/bin/sh f= $(basename $1) f2py -h $f.pyf -m $f $f.f90 In my main script I am using following: find "$main_dir/source_code/3DBGB/" . -name '*.f90' -exec $main_dir/callf2py.sh {} \;
    – Syed Moez
    Jun 8, 2015 at 16:34
  • Sorry I am not able to edit my above comment properly.
    – Syed Moez
    Jun 8, 2015 at 16:37
  • 1
    it's hard to tell from your unformatted comment; can you show a sample run with the error? you might have an extra space between f= and $(basename $1)
    – Jeff Schaller
    Jun 9, 2015 at 0:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .