1

I have a folder with multiple .wav files that I am trying to concatenate in order but I think that I am too inexperienced with bash commands to do this as efficient as possible. You see, I don't know how to use a files content as input for a command:

I get all the file names in correct order with:

ls *.wav | sort -V > script

Script:

ep1-s1.wav
ep2-s1.wav
ep3-s1.wav

I add ' \' after each line to use in the command

lam script -s " \\" > script2

Script2:

ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav \

I delete the last ' \':

sed '$ s/.$//' script2 > script3

Script3:

ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav

And now I want to use the content of that file for the sox, like:

sox ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav output.wav

How can I achieve this?

Now, there is probably a way to do this in one command, but I couldn't figure out how piping works like that: if you know how to, I would really love to know!

Bart
  • 85
  • I'm not familiar with sox. Could you give an example of the command you would like to run and we can help you build a script to generate that command? – David King May 21 '18 at 19:50
  • that's probably a job for xargs – A.B May 21 '18 at 19:55
  • @A.B Wow, you're totally right. I was completely overthinking this whole thing. I guess I learned a few new things from it, but this was way easier than I thought: thanks! – Bart May 21 '18 at 19:55
  • depends if you need to sort in versioning order, that's why I deleted the comment. but look at xargs if you really need this sort -V – A.B May 21 '18 at 19:56
  • Yea, I just noticed, that's not in the correct version ordering, I thought that it was. – Bart May 21 '18 at 20:03
  • @DavidKing I want to run a command like this: sox ep1-s1.wav ep2-s1.wav ep3-s1.wav output.wav but I want to create the ep1-s1.wav ep2-s1.wav ep3-s1.wav part dynamically, depending on the files in the directory and in order using: ls *.wav | sort -V > script – Bart May 21 '18 at 20:05
  • How about just sox *wav? Given your example filenames and normal Linux locale settings this would work. – m0dular May 21 '18 at 20:22

3 Answers3

2

Like I mentioned in a comment, if you don't need version sorting (sort -V), you can simply do sox *wav. In Linux, *wav will undergo filename expansion, resulting in a list of alphabetically sorted filenames. This is affected by your locale settings, particularly LC_COLLATE, which you can Google for more info.

If you need sort -V, the right way to handle this is with null terminated strings and arrays to handle filenames with spaces and other special characters. This script will put the output of the sort command into an array and run sox with this list.

#!/bin/bash

unset wav_files

while IFS= read -r -d '' file; do
   wav_files+=("$file")
done < <(find . -maxdepth 1 -type f -name "*wav" -print0 | sort -V -z)

if (( ${#wav_files[@]} == 0 )); then
   echo "No wav files found"
else
   sox -- "${wav_files[@]}"
fi

This might be more than you were expecting, but it's good practice ;)

m0dular
  • 1,261
0

If and only if your filenames are "nice", and don't contain whitespace or special characters (esp. glob characters), the easy way out is to run sort in a command substitution:

sox $(printf "%s\n" *.wav | sort -V) output.wav

The printf here works to put newlines (\n) after each filename.

(As usual, an unquoted expansion like that will break if the filenames have spaces or tabs (they'll be split in two after the $(...) is expanded); or newlines (they'll be split in two before the sort); or glob characters (*?[], they'll expand to any matching file names). So don't do that if you don't know the filenames are nice enough. See e.g. https://mywiki.wooledge.org/WordSplitting and When is double-quoting necessary?

ilkkachu
  • 138,973
-2

Why not try :

sox `ls *.wax | sort -V`
Joe M
  • 876