コマンド(ls)の出力を他のコマンドの入力(sox)にどのように使用できますか?

コマンド(ls)の出力を他のコマンドの入力(sox)にどのように使用できますか?

順番にリンクしようとしている複数の.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つのコマンドでこれを行う方法があるかもしれませんが、パイプがどのように機能するかはわかりません。方法を知っていれば本当に知りたいです!

答え1

コメントで述べたように、バージョンソート()が必要ない場合は、sort -V簡単に実行できますsox *wav。 Linuxでは、*wavファイル名拡張が行われ、アルファベット順にソートされたファイル名のリストが生成されます。これはあなたのロケールの影響を受け、特にLC_COLLATEGoogleで詳細を見ることができます。

必要に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

(通常のようにファイル名にスペースまたはタブがある場合($(...)拡張後に2つの部分に分割されている)、改行文字(前に2つに分割されているsort)またはグローバル文字(*?[]、一致するファイル名に展開されます。)、したがってファイル名がわからない場合は、これを行わないでください。https://mywiki.wooledge.org/WordSplittingそして いつ二重引用符が必要ですか?

答え3

一度試してみてください。

sox `ls *.wax | sort -V`

関連情報