简体   繁体   中英

Bash - Directory dependent script

I am trying to run a python script in a directory and using bash apply this script to each of its subdirectories.

I found a script on unix stack exchange that does it for 1 set of subdirectories here . But I want it to recursively work for all sub-directories .

The problem is I have a single wav.py in the parent directory but none in the sub-directories.

for d in ./*/ ; do (cd "$d" && python3 $1 SA1.wav); done

As you can see $1 (wav.py) is the path to my python file set when I call the bash script. I would also like the path to be relative to how many levels of the subdirectory tree I have traversed. I know I can use an absolute path. But it will cause issues later on, so I'd like to avoid it.

Eg. for 1 level

for d in ./*/ ; do (cd "$d" && python3 "../$1" SA1.wav); done

for 2 levels

for d in ./*/ ; do (cd "$d" && python3 "../../$1" SA1.wav); done

Sorry if this seems trivial. I'm still new to bash.

Additional Info:

This is my full directory path:

root@Chiku-Y700:/mnt/e/Code/Python - WorkSpace/timit/TIMIT/TEST/DR1# bash recursive.sh wav.py suit rag

the full command I'm trying to run is:

python3 $1 SA1.wav $2 SA2.wav $3

$2 and $3 are unrelated to any directory info.

I get:

python3: can't open file '/mnt/e/Code/Python': [Errno 2] No such file or directory

This error came 12 times for 11 subdirectories.

Let's look at your command, with wav.py being $1:

for d in ./*/ ; do (cd "$d" && python3 $1 SA1.wav); done

Can we reduce the complexity by making wav.py executable and giving it a shebang, so that you can call it directly? Then you may move it to your PATH or temporarily putting the location, where it sits, into the path. It's generally best habit, that your script does not depend upon the place, from where it is invoked, especially that it isn't needed to be in the same directory from where it is called.

PATH=$PWD:$PATH
for d in ./*/ ; do (cd "$d" && wav.py SA1.wav); done

The input data should not depend on the same directory restriction, so that you can call it from every dir and with the data being in an arbitrary dir, too:

for d in ./*/ ; do wav.py $d/SA1.wav; done

Probably, you produce an output file, which is written to the current directory, then you either should extract the output dir from the input dir, if this is what you always want to achieve, or let the user specify an output dir. A default outputdir might still be the inputdir or the current dir. Or you write to STDOUT, and pipe the output to a file, located to your choice.

But your full command is:

python3 $1 SA1.wav $2 SA2.wav $3

That's fine for simple commands, but maybe you can name these parameters in a meaningful way:

pyprog="$1"
samplerate="$2"
log="$3"

python3 $pyprog SA1.wav $samplerate SA2.wav $log

or, as done before

$pyprog SA1.wav "$samplerate" SA2.wav "$log"

Then, John1024s solution might work:

find . -type d -execdir $pyprog SA1.wav "$samplerate" SA2.wav "$log" ";"

If changing pyprog is not an option, there is a second approach to solve the problem:

Write a wrapper script, which takes the directory to work in as a parameter and test it with different depths of directories.

Then call that wrapper by find:

find . -type d -exec ./wrapper.sh {} ";"

The wrapper.sh should start with:

#/bin/bash
#
#
directory="$1" 

and use it where needed.

Btw.: I would rename the Python - WorkSpace to Python-WorkSpace (even better: python-workSpace ) too, because blanks in file and path names always cause trouble.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM