ディレクトリのリストを find コマンドに渡します。

ディレクトリのリストを find コマンドに渡します。

findコマンドにディレクトリリストをどのように渡しますか?

次のようにリストを取得すると想像してください。

ls -d mydir*/

これによりmydir1、mydir2などが出力されますが、otherdirs1、otherdirs2は除外されます。

リストから次のコマンドを実行したいと思います。

find <put here the name of each dir>  -type f -name "*.mp3" -print0 | xargs -0 ...

各ディレクトリで個別にこのコマンドを実行してみてください。

find -type f -name "*.mp3" -print0 |
xargs -0  mplayer -vo dummy -ao dummy -identify 2>/dev/null |
 perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t +=$1) && printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60' |
 tail -n 1

つまり、mp3を探し、mplayerを実行して各ファイルのメタデータを取得し、各mp3ファイルのすべてのID_LENGTHの合計を計算し、ディレクトリ内のすべてのmp3の合計を出力します。

答え1

ls -d渡した内容を正確にリストします(存在しないファイルを除く)。したがって、名前がmydir次に始まるディレクトリが1つ以上あるとします。

find mydir*/ -type f -name .mp3 -print0 | …

mydir*/ディレクトリへのシンボリックリンクが一致し、リンクされたfindディレクトリが巡回されることに注意してください。

xargs可能な限り少ないパラメータでコマンドを実行し、一度に複数の引数を渡すのが一般的です。各ファイルに対して個別にコマンドを実行する必要がある場合は、次のように指定します。

find mydir*/ -type f -name .mp3 -print0 |
xargs -0 -n1 mplayer … |
perl …

または簡単な作業を行い、-execオプションを使用してくださいfindfindエラーを個別にフィルタリングする機能は失われますmplayer

find mydir*/ -type f -name .mp3 -exec mplayer -vo dummy -ao dummy -identify {} \; 2>/dev/null |
perl …

しかし、最後の行だけが必要ですが、なぜすべての行を印刷するのですか?

… | perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t +=$1); END {printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60}'

また、これを使用して、run後のbash shopt -s globstar、run後のksh、またはデフォルトでzshからサブディレクトリのファイルを再帰的に一致させることもできます。set -o globstar**

mycommand mydir*/**/*.mp3
for f in mydir*/**/*.mp3; do …

これは、名前で終わるディレクトリとシンボリックリンクとも一致します.mp3。 Bashはディレクトリのシンボリックリンクを巡回しますが、kshとzshはディレクトリのシンボリックリンクをmydir*巡回しますが、繰り返しはシンボリックリンクを省略します。

for f in mydir*/**/*.mp3; do
  mplayer -vo dummy -ao dummy -identify "$f" 2>/dev/null
done | perl …

ksh93とzsh(bash、dash、またはpdkshを除く)には浮動小数点演算があるため、合計を計算するためにPerlなどの他のツールを呼び出す必要はありません。

typeset -F length=0
for f in mydir*/**/*.mp3; do
  length+=$(mplayer -vo dummy -ao dummy -identify "$f" 2>/dev/null |
            sed -n 's/^ID_LENGTH=//p')
done | perl …
printf "%02d:%02d:%02d\n" $((t/3600)) $((t/60%60)) $((t%60))

関連情報