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
オプションを使用してくださいfind
。find
エラーを個別にフィルタリングする機能は失われます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))