アプリ版:「スタンプのみでお礼する」機能のリリースについて

あるディレクトリにある .wma ファイルを全て .mp3 ファイルに
変換するスクリプトを作りたいです。

例えばそのディレクトリの中が
hoge.mp3
foo.mp3
bar.mp3
となっていたら、
ls > ls.txt
をした後に
ls.txt の中を一行一行読み込んで .wma の前を変数 var に代入し、
ffmpeg -i ${var}.wma ${var}.mp3
という風にやれば良いと思うのですが、
.wma の前を変数 var に代入するやり方が分かりません。
なるべく . の後が3文字の .mp3 だけでなく .list などでも通用する方法を知りたいです。

どうぞご教授下さい。
よろしくお願いします。

A 回答 (8件)

  (場合によってはリストを手動加工するので?)


ls.txt を用意するうという条件下で
cat | while read するシェルの例をあげましたが、
ご指摘の通り、この方法だと大量のファイルや、長いファイル名があるとき、
シェルのコマンドラインの長さ制限に引っかかってしまいますね。

そういう場合を考慮するなら、 ワイルドカード使わないで
find ./ -name '*.wma' -print | while read line;do ffmpeg -i ${line} ${line%.*}.mp3;done
かな。
    • good
    • 0
この回答へのお礼

ネストされた構文がよく分からなかったのですが、
中身が
2
7
となっている bit.txt を用意した場合は

$ cat bit.txt | while read line;do let line="${line} + 1" ; echo $line ;done
3
8

と、きちんとうまくいきました。
どうもありがとうございました。

お礼日時:2014/11/26 09:29

#7 のところ, 「ネストされた構文」ってのはどれのことでしょうか?



ついでに
ls | grep wma > ls.txt
だと「拡張子が .wma でないもの」もリストアップされます.
grep '\\.wma$'
なら大丈夫かな?

この回答への補足

すみません、
ls |
の部分を最初に付けずに
$ grep '\\.wma$'
$ grep '\.wma$'
と入力するというバカなことをやってしまいました。

a.pdf
pdf_in_name.txt
の2つのファイルが存在するディレクトリでのコマンド実行結果は

$ ls | grep pdf
a.pdf
pdf_in_name.txt
$ ls | grep '\\.pdf$'
$ ls | grep '\\.pdf'
$ ls | grep '\.pdf$'
a.pdf
$ ls | grep '\.pdf'
a.pdf

となりました。

補足日時:2014/11/28 18:03
    • good
    • 0
この回答へのお礼

ありがとうございます。
> #7 のところ, 「ネストされた構文」ってのはどれのことでしょうか?
すみません、書き間違えました。次の文ですが、

$ cat bit.txt | while read line;do let line="${line} + 1" ; echo $line ;done

while ループの中に複数の文が入っているもの、
という意味で書いたつもりでした。

do ~ done のなかに
単に複数の文を ; でつないで書けば良い、
ということが分からなかったのです。

grep '\\.wma$'
grep '\.wma$'
のどちらを試してもターミナルが固まってしまい、反応がありません。

お礼日時:2014/11/27 23:24

本題からいくと, find の結果は #2 の


cat ls.txt
相当なので, cat ls.txt の代わりに「find 以下省略」を入れればいい.

余談については「find が何をするか」を考えればいい. find は
1. 指定した場所から
2. 指定した条件を満たすファイル (やディレクトリなど) に対して
3. 指定した動作を実行する
というプログラムで, 条件と動作については何も与えないときのデフォルトは
2'. すべてのファイル (やディレクトリなど) に対して
3'. そのパスを表示する
になってる (この辺まではマニュアルに書いてあるはず). これを踏まえつつ
find *.wma
を見ると, 場所として *.wma (を展開したもの) が与えられているが条件や動作が書かれていないのでデフォルトの処理をする. つまり *.wma (を展開したもの) 以下のすべてのファイル (やディレクトリなど) を表示するわけだから, 結果として
ls -1R *.wma
と似たような動作になる.
    • good
    • 0
この回答へのお礼

おかげさまでよく理解できました。
詳しく解説していただき、誠にありがとうございます。

お礼日時:2014/11/26 09:29

まず, その find の使い方は変だ. マニュアルで確認するように. 特に -name あたり.



例えば
ls *.wma
としたとき, ワイルドカードはシェルが展開する. で, もしいっぱいファイルがあって「コマンドラインの長さの限界」を越えたらどうなるか知ってる?

コマンドラインの長さの限界を越えないことが確実だとしても,
ls > ls.txt
みたいにわざわざファイルを作る必要はあるんでしょうか.

もちろん, ファイルを作るにしても (「コマンドラインの長さ」は関係なく) ls よりは find の方が適切な選択ではある.

この回答への補足

ls を使う場合でも
ls | grep wma > ls.txt
とすれば問題ないですね。

補足日時:2014/11/26 09:28
    • good
    • 0
この回答へのお礼

ありがとうございます。
「コマンドラインの長さ限界」の問題を考慮すると、
正しくは
$ find -name '*.wma'
ですね。
しかし、
$ find *.wma
でなぜこちらが期待する結果が出たのかよく分からないです。
(本筋から外れたことですが)

> ls > ls.txt
> みたいにわざわざファイルを作る必要はあるんでしょうか.
シェルスクリプトの知識が不足していますので、
ls.txt などを作らずに処理するやり方が分からないのです。
find -name '*.wma' | read line ; var=${line%.*} ; ffmpeg -i ${line} ${var}.mp3
find -name '*.wma' | var=${line%.*} ; ffmpeg -i ${line} ${var}.mp3
などではいまくいきませんし。

お礼日時:2014/11/25 15:03

このサイトって、インデント表示する方法ないみたいないので、


行頭に全角空白入れて書いてしまったけど、
コピペするんじゃなくて半角に。
    • good
    • 0
この回答へのお礼

回答No.2で
全角とか半角とか書いてあるのが何のことかわからなかったのですが、
行頭に全角スペースが入れてあったのですね。
そこを修正したら、ちゃんと動作しました。
どうもありがとうございました。

お礼日時:2014/11/25 15:01

「.wma の前を変数 var に代入する」のは #2 の通りでいいんだけど


ls *.wma
はいただけない.
・単に for でまわす
・find を使う
のどちらかにすべきだ.
    • good
    • 0
この回答へのお礼

ありがとうございます。

> 「.wma の前を変数 var に代入する」のは #2 の通りでいいんだけど
ここが今引っかかっている所です。
自分でも少し調べてみます。

> ls *.wma
> はいただけない.
ターミナル上では

$ find *.wma
01.wma
02.wma
$ ls *.wma
01.wma 02.wma

ですが、

$ ls *.wma > ls.txt
$ cat ls.txt
01.wma
02.wma

というように、ちゃんと一行にファイルがひとつづつ出力されていて問題ないようです。

お礼日時:2014/11/24 23:31

ls *.wma > ls.txt



cat ls.txt | while read line ; do
 var=${line%.*}
 ffmpeg -i ${line} ${var}.mp3
done

かな。
(全角空白は半角に)

拡張子を足したいときは、 1行目を  ls *.wma *.wav > ls.txt といった感じにするだけです。
ただ、listファイルというのが、音声ファイルや動画ファイルでなく、
再生順を記載したプレイリスト(単なるテキストファイル)のことでしたら、
エンコード形式を変換する対象にはならないのでは?
    • good
    • 0
この回答へのお礼

ありがとうございます。
やってみたのですが、ffmpeg がインストールされているのにうまくいきません。

cat ls.txt | while read line ; do
 var=${line%.*}
echo $line,$var
 ffmpeg -i ${line} ${var}.mp3
done

としたスクリプトの結果が次のようになります。

$ bash script.sh
script.sh: 行 2: $'\343\200\200var=01': コマンドが見つかりません
01.wma,
script.sh: 行 4: $'\343\200\200ffmpeg': コマンドが見つかりません
script.sh: 行 2: $'\343\200\200var=02': コマンドが見つかりません
02.wma,
script.sh: 行 4: $'\343\200\200ffmpeg': コマンドが見つかりません

> なるべく . の後が3文字の .mp3 だけでなく .list などでも通用する方法を知りたいです。

> listファイルというのが、音声ファイルや動画ファイルでなく、
> 再生順を記載したプレイリスト(単なるテキストファイル)のことでしたら、
> エンコード形式を変換する対象にはならないのでは?

.list 自体に特に意味はなく、
別のコマンドで別の処理をする時にもすぐに応用が効くやり方を教えて下さい、
という意味で書いたのですが、言葉足らずだったようで分かりにくかったですね。
申し訳ありません。

お礼日時:2014/11/24 23:18

使ってるシェルはなに?

    • good
    • 0
この回答へのお礼

ありがとうございます。
debian wheezy(7.7) を使用していますので、bash です。

お礼日時:2014/11/24 08:30

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!