I have a little programming experience but am completely new to shell scripting.

I have several hundred mp3s which I want to split using mp3splt with the command

mp3splt -A XXX.txt XXX.mp3

I have run this command by hand in the past but now have a project where doing it by hand would be impractical due to the number of files. In my imagination it should be easy to write a script that searches a folder for all the mp3s that have a txt file of the same name and runs the above command on them.

My question just is this: Is there any obvious reason this would not work? If you (meaning: a person with experience in shell scripting) don´t see any such reason, I´d work my way through this tutorial to work out the rest. If, on the other hand, you say it is impossible, I can just stop and do it by hand.

Thanks in advance!

In case you are interested in my use case: I play irish music, which is based on short melodies played by heart. I want to learn these melodies using anki with audio files. For that, I need to have audio files with just one specific tune each.

  • sjohannes@programming.dev
    link
    fedilink
    English
    arrow-up
    4
    ·
    2 days ago

    I don’t think that works, because the command substitution in "$(…).txt" runs immediately in the current shell.

    Aside from that, find -exec doesn’t use a shell to run its command, which means $(…) won’t work without an explicit sh call.

    I believe the right command in this style that will work is:

    find /my/mp3dir -type f -iname '*.mp3' -exec sh -c \
      'test -f "${0%.mp3}.txt" && mp3splt -A "${0%.mp3}.txt" "$0"' \
      '{}' ';'
    

    However, I would recommend the for f in *.mp3-style solution instead, as to me it’s more readable. (The Bash/Zsh recursive glob (**) syntax can be used if subdirectories are involved.)

    • DollyDuller@programming.dev
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      2 days ago

      You’re correct about command substitutions, the $(...) part. I had initially thought putting it inside a sh would be clearer and avoid problems with substitutions. However, $0 is the name of the shell or the script. To fix this, we can put {} inside a variable, like this: file="{}". Then, we can use the variable $file for the rest of the command.

      I also think using for loops makes the command easier to read. But dealing with files that have spaces in their names can be really frustrating when you use for loops.