bash-lsをカスタムスクリプトにリダイレクトする
質問
大学のために私はmp3ファイルのid3タグを読んで表示するスクリプトを書いています。引数はファイルになります。
./id3.sh file1.mp3 file2.mp3 morefiles.mp3
私は以下を使って引数を読むことができます $0, $1
など。そして、引数の数を取得します $#
.lsコマンドから出力を読み取るにはどうすればよいですか?
ls *.mp3 | ./id3.sh
解決
私は id3.sh スクリプトを下の例では、 strong>スクリプトをで呼び出されます。Frong> xargs
によってリストされています。これは非常に重要です。特にあなたがリスト内に一千のファイルや何千ものファイルを持つことができる場合は特に重要です。ls *.mp3
を省略すると、リスト全体を持つのみと呼ばれます。リストが長すぎる場合、システムはスクリプトを実行することを拒否する可能性があります。プロセスするスクリプトを各呼び出しにどのくらいのファイルを処理するかを実験することができます(例えば、あなたの場合はより効率的なもの)。
ls *.mp3 | xargs -n 10 id3.sh
.
その後、この
のような id3.sh スクリプトのファイルを読むことができます。while [ "$1" != "" ]; do
#next file available in ${1}
shift
done
. 他のヒント
これを試してみてください:
ls *.mp3 | xargs id3.sh
. ls *.mp3 > ./id3.sh
コマンドは、id3.shスクリプトをMP3のリストで上書きしようとしています。あなたはこれを試すことができます:
./id3.sh `ls *.mp3`
.
編集:実際、私は何を考えていましたか?これを行うことができない理由はありますか?
./id3.sh *.mp3
. .MP3ファイルの数が非常に大きい場合、*.mp3
リスクの拡張が失敗した場合は、結果として得られる展開された*.mp3
がシェルの制限を超えています。上記の解決策すべてにこの問題がある:
ls *.mp3 | ...
for file in *.mp3; do ...
.
実際には、ls *.mp3|xargs ...
が良いスタートですが、シェルが*.mp3
リストを拡張し、そのリストをls
コマンドにコマンドライン引数として使用する必要があるため、同じ問題があります。
任意の数のファイルを正しく処理する1つの方法は次のとおりです。
find . -maxdepth 1 -iname '*.mp3'|while read f; do
do_something_one_file_at_a_time.sh "$f"
done
.
または:
find . -maxdepth 1 -iname '*.mp3' -print0|xargs -0 do_something.sh
.
(両方の変形例は、スペースでファイル名を適切に取り扱うことの側面の利点を有する。「雨滴は私の頭の上に落ち続ける」
do_someth.shでは、for file in "$@"; do ...
またはfor file in $*;do ...
だけではなく、for file in $@; do ...
を実行する必要があります。
スペースを持つファイル名がある場合は、amit_gの解決策が壊れることにも注意してください。)
何が問題なのか ./id3.sh *.mp3
?それは との解決より安全 ls
, 、とまったく同じglobbing機能を提供します。必要はありません xargs
ここでは、あなたが使用している場合を除き 古いカーネル と 持っている 膨大な量のファイル.
./id3.sh *.mp3 # if the number of files is not too many
.
または
ls *.mp3 | xargs -n 10 ./id3.sh # if the number of files could be too many
.
その後id3.sh
while [ "$1" != "" ]
do
filename=$1
#do whatever with $filename
shift
done
.