0

Dear stackoverflow community,

I am new to bash and I've got a problem regarding loops and directories (code below). So I am working in the opensmile directory and want to look for .wav files in the subdirectory opensmile/test-audio/. But if I change my directory in the "for" section to test-audio/*.wav, it probably could find the .wav-files but then the main-action does have access to the necessary config file "IS10_paraling.conf". Within the main-action the directories have to be written like after "-C", so without a "/" before the directory.

My loop works, if the wav files are inside the opensmile directory, but not inside a sub-directory. I would like to look for files in the subdirectory test-audio while the main-action still has access to all of the opensmile-directory.

So basically: How do I go up and down directories within a for loop?

Thank you very much in advance!

This works

#! /bin/bash
cd /usr/local/opensmile/

for f in *.wav; 
do
/usr/local/opensmile/build/progsrc/smilextract/SMILExtract -C config/is09-13/IS10_paraling.conf -I $f -D output/$f.csv ;
done

This does not work

#! /bin/bash
cd /usr/local/opensmile/

for f in test-audio/*.wav; 
do
/usr/local/opensmile/build/progsrc/smilextract/SMILExtract -C config/is09-13/IS10_paraling.conf -I $f -D output/$f.csv ;
done
bash-asker
  • 41
  • 5
  • On your second, not working attempt, your variable `f` will contain something like `test-audio/xxx.wav` so your command will use `-D output/test-audio/xxx.wav.csv` – Mark Setchell Jul 09 '22 at 13:29
  • Thank you for your comment. Yes, that is true. Also, the config file in the folder `opensmile/config/is09-13/` lays one folder above the `opensmile/test-audio/` folder. I would like `f` to only search for the `.wav` in `opensmile/test-audio/` folder, but have the main-action run in the index folder `opensmile/`. Is that possible? – bash-asker Jul 09 '22 at 14:23
  • why do you think path argument to `-C` cannot begin with `/` ? – jhnc Jul 09 '22 at 19:05
  • I'm sorry, I just tested it again, and path argument to `-C` _can_ actually begin with `/`. Still unfortunately I have tried the whole afternoon and I could not find an answer. I tried to put `ls` and the subdirectory into two variables to be able to have two directories in one for loop. But either (1)`f` will find the `wav` files in the subdirectory BUT cannot reach the config file in the other sub directory AND will write the subdirectory into the output name or (2) it will search in the main directory, but cannot reach the wav files because they are in the subdirectory. Can somebody help? – bash-asker Jul 09 '22 at 21:10

2 Answers2

0

Saying "this does not work", doesn't tell us anything. What happens? Is there an error message?

Nevertheless, your question was "So basically: How do I go up and down directories within a for loop?"

If I'm tempted to go up and down directories within a loop, I'll do it in a subshell, so that I can be sure that the next time I enter the loop I'll be where I was originally. So I'll put all my commands in ( ).

#! /bin/bash
cd /usr/local/opensmile/
CONFIG=$PWD/config
OUTPUT=$PWD/output

for f in test-audio/*.wav; 
do
 (
  cd test-audio
/usr/local/opensmile/build/progsrc/smilextract/SMILExtract -C $CONFIG/is09-13/IS10_paraling.conf -I `basename $f` -D $OUTPUT/$f.csv
 )
done

though why one would need to to it for this case, I can't fathom

xpusostomos
  • 1,309
  • 11
  • 15
  • Thank you for your answer. I tried your suggestion and the output shows a similar error to my other attempts: `(ERR) [1] cCsvSink: Error opening file '/usr/local/opensmile/output/test-audio/VA03.000389_1.wav.csv' for writing (component instance 'lldsink', type 'cCsvSink')` It tried putting the whole segment of the loop arguement after the -D. There is no folder "test-audio" in the output folder though, I suppose that this is why the error message comes. – bash-asker Jul 10 '22 at 09:04
  • I also varied your code like this `for f in test-audio/*.wav; ` . Now there is no error message and there is an output file. Unfortunately the output file is named `*.wav.csv`. It should be named `VA03.000389_1.wav.csv`. – bash-asker Jul 10 '22 at 09:13
  • try -D $OUTPUT/\`basename $f\`.csv – xpusostomos Jul 10 '22 at 12:03
  • or -D $OUTPUT/\`basename $f .wav\`.csv – xpusostomos Jul 10 '22 at 12:04
  • Thank you for your suggestions. Both suggestions put out only ONE file in the output folder called `VA01.000306_1.wav`. It has the suffix `.wav` but is in fact a csv file, when you rename the wav section. There is only one file in the output, but the input folder `test-audio` has three audio files. The "working" example in my initial question puts out three `csv` files (one `csv` file for each `wav` file). – bash-asker Jul 10 '22 at 16:20
  • I also tried (1) -D $OUTPUT/basename $f.csv (2) -D $OUTPUT/basename $f .wav.csv (3) -D $OUTPUT/´basename $f.csv´ and (4) -D $OUTPUT/´basename$f.csv´. (1) and (2) both put out one file called "basename" without suffix. (3) puts out one file called *.wav.csv. (4) Shows the following error: (ERR) [1] cCsvSink: Error opening file '/usr/local/opensmile/output/' for writing (component instance 'lldsink', type 'cCsvSink') P.S. I turned the apostrophes the other way because stackoverflow makes it code if I use the original ones – bash-asker Jul 10 '22 at 16:30
0

Instead of using a for loop, could you use find for this:

find /usr/local/opensmile/ -type f -name "*.wav" -exec /usr/local/opensmile/build/progsrc/smilextract/SMILExtract -C config/is09-13/IS10_paraling.conf -I $1 -D output/$1.csv "{}" \;

CJW
  • 710
  • 9
  • 26
  • Thank you for your reply, CJW! Unfortunately this puts out an error message: `(ERR) [1] cWaveSource: failed to open input file '-D'` The syntax seems to skip the $1 segment and jump on. I was not sure if you meant to write $f instead of $1. I tried both, but the error message is the same for both. – bash-asker Jul 11 '22 at 08:29
  • Does anyone have any more ideas? – bash-asker Jul 13 '22 at 09:44