我有一个包含多个 .wav 文件的文件夹,我试图按顺序连接这些文件,但我认为我对 bash 命令缺乏经验,无法尽可能高效地执行此操作。你看,我不知道如何使用文件内容作为命令的输入:
我以正确的顺序获取所有文件名:
ls *.wav | sort -V > script
脚本:
ep1-s1.wav
ep2-s1.wav
ep3-s1.wav
我在每行后面添加“\”以在命令中使用
lam script -s " \\" > script2
脚本2:
ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav \
我删除最后一个'\':
sed '$ s/.$//' script2 > script3
脚本3:
ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav
现在我想将该文件的内容用于sox
,例如:
sox ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav output.wav
我怎样才能实现这个目标?
现在,可能有一种方法可以在一个命令中执行此操作,但我无法弄清楚管道是如何工作的:如果您知道如何操作,我真的很想知道!
答案1
就像我在评论中提到的,如果您不需要版本排序 ( sort -V
),您可以简单地执行sox *wav
.在 Linux 中,*wav
将进行文件名扩展,产生按字母顺序排序的文件名列表。这受到您的区域设置的影响,尤其是LC_COLLATE
,您可以通过 Google 获取更多信息。
如果您需要sort -V
,处理此问题的正确方法是使用以 null 结尾的字符串和数组来处理带有空格和其他特殊字符的文件名。该脚本会将命令的输出放入sort
一个数组中,并sox
使用该列表运行。
#!/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
这可能超出您的预期,但这是一个很好的做法;)
答案2
当且仅当sort
您的文件名“很好”,并且不包含空格或特殊字符(尤其是 glob 字符),简单的方法是在命令替换中运行:
sox $(printf "%s\n" *.wav | sort -V) output.wav
这里printf
的作用是在每个文件名后面添加换行符 ( \n
)。
(像往常一样,如果文件名有空格或制表符(在$(...)
展开后它们将被分成两部分);或换行符(它们将在 之前被分成两部分sort
);或全局字符(*?[]
,它们会扩展到任何匹配的文件名),所以如果您不知道文件名足够好,请不要这样做,请参见例如。https://mywiki.wooledge.org/WordSplitting和 什么时候需要双引号?
答案3
为什么不尝试一下:
sox `ls *.wax | sort -V`