如何附加一堆 .wav 文件同时保留(非零填充的)数字顺序?

如何附加一堆 .wav 文件同时保留(非零填充的)数字顺序?

我有许多 (7500) 个 .wav 文件(按其编号命名),我想将它们合并为一个。我认为这必须使用 bash 循环来完成,因为使用通配符时,某些文件的顺序会错误(例如 1111 在 2 之前)。

在 Linux 下执行此操作的最佳方法是什么?

答案1

如果所有文件都具有相同的参数,例如采样率和声道数,您仍然无法将它们连接起来。您必须去掉 WAV 标头。

最简单的方法可能是使用音频文件处理实用程序,例如sox,它包含连接文件的方法。事实上,它默认执行此操作。例如,将三个 .wav 文件合并为一个长文件:

$ sox short1.wav short2.wav short3.wav long.wav

循环不会按您想要的顺序排列文件。您想要的是按名称排序,但按数字处理它们。sort -n将执行此操作。

因此:

$ sox $(ls *.wav | sort -n) out.wav

如果sox无法处理那么多文件,我们可以像这样分解工作:

$ ls *.wav | sort -n > script

然后我们有一个如下所示的脚本文件:

1.wav
2.wav
...
3999.wav
4000.wav
...
file7500.wav

我们对其进行编辑以制作几条命令行:

# catenate about half the files to temp1.wav   
sox \
1.wav \
2.wav \
... \
3999.wav \
temp1.wav

# catenate the remainder to temp2.wav  
sox \
4000.wav \
... \
7500.wav \
temp2.wav

# catenate the two halves
sox temp1.wav temp2.wav out.wav ; rm temp1.wav temp2.wav

作为文件列表的第一步编辑步骤,您可以使用该vi命令:%s/.*/& \\/在每一行后添加反斜杠。

答案2

今天这个问题一直困扰着我,因为我要连接的文件比 sox 可以加载的要多得多。所以我最终在包含 wavs 的文件夹中使用了此 shell 脚本(请确保您不需要 in.wav 和 out.wav,因为它们将被覆盖):

rm in.wav out.wav                                                                                                                            
ls *.wav | sort -n | while read l;
do                                                                                                                                                            
   if [ ! -f in.wav ]                                                                                                                                         
   then                                                                                                                                                       
      cp $l in.wav                                                                                                                                            
   else                                                                                                                                                       
      sox in.wav $l out.wav                                                                                                                                   
      cp out.wav in.wav                                                                                                                                       
   fi                                                                                                                                                         
   echo "$l"                                                                                                                                                  
done        
``

相关内容