make
を使用してからしばらく経ちました。
.FLACファイルを含むflac
ディレクトリがあります。 MP3ファイルを含むmp3
という対応するディレクトリがあります。 FLACファイルが対応するMP3ファイルよりも新しい(または対応するMP3ファイルが存在しない)場合、FLACファイルをMP3ファイルに変換するためのコマンドを実行し、タグをコピーします。
キッカー:flac
ディレクトリを再帰的に検索し、mp3
ディレクトリに対応するサブディレクトリを作成する必要があります。ディレクトリとファイルには名前にスペースを含めることができ、UTF-8で名前が付けられます。
そして、make
を使用してこれを駆動します。
私はこれらの線に沿って何かをしようとします
_FLAC_FILES = $(Shell find flac/ -type f -name '*.flac')
MP3_FILES = $(patsubst flac/%.flac, mp3/%.mp3, $(FLAC_FILES))
.PHONY: all
all: $(MP3_FILES)
mp3/%.mp3: flac/%.flac
@mkdir -p "$(@D)"
@echo convert "$<" to "$@"
_
make
初心者向けの簡単なメモ:
@
_は、make
が実際に実行する前にコマンドを出力しないようにします。$(@D)
はターゲットファイル名のディレクトリ部分です(_$@
_)これがすべてのUTF-8文字とものを処理する必要がある場合でも、make
はスペースを使用してメイクファイル内のものを分離するため、ファイル名またはディレクトリ名のスペースで失敗し、回避方法はわかりませんそれ。そのため、シェルスクリプトだけが残ります。
次のように、独自の再帰的なワイルドカード関数を定義できます。
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
最初のパラメーター($1
)はディレクトリ名で、2番目のパラメーター($2
)は照合するパターンです。
現在のディレクトリですべてのCファイルを見つけるには:
$(call rwildcard, , *.c)
src
内のすべての.c
および.h
ファイルを見つけるには:
$(call rwildcard, src/, *.c *.h)
FWIW、私はこのようなものをMakefileで使用しました:
RECURSIVE_MANIFEST = `find . -type f -print`
上記の例では、現在のディレクトリ('。')からすべての「プレーンファイル」('-type f')を検索し、RECURSIVE_MANIFEST
見つかったすべてのファイルに変数を作成します。次に、パターン置換を使用してこのリストを減らすか、またはfindにさらに引数を指定して、返されるものを絞り込むことができます。 findのマニュアルページを参照してください。
私の解決策は上記のものに基づいており、sed
の代わりにpatsubst
を使用してfind
の出力をマングルし、スペースをエスケープします。
Flac /からogg /へ行く
OGGS = $(Shell find flac -type f -name "*.flac" | sed 's/ /\\ /g;s/flac\//ogg\//;s/\.flac/\.ogg/' )
警告:
以下は、元の問題を解決するためにすばやくハッキングしたPythonスクリプトです。音楽ライブラリの圧縮コピーを保持します。 AACファイルが既に存在し、ALACファイルよりも新しい場合を除き、スクリプトは.m4aファイル(ALACと想定)をAAC形式に変換します。ライブラリ内のMP3ファイルは既に圧縮されているため、リンクされます。
スクリプトを中止することに注意してください(ctrl-c)は、半分変換されたファイルを残します。
私はもともとこれを処理するためにMakefileを書きたいと思っていましたが、ファイル名のスペースを処理できないため(受け入れられた答えを参照)、bashスクリプトを書くと苦痛の世界に陥りますPythonです。かなり簡単で短いため、ニーズに合わせて簡単に調整できます。
from __future__ import print_function
import glob
import os
import subprocess
UNCOMPRESSED_DIR = 'Music'
COMPRESSED = 'compressed_'
UNCOMPRESSED_EXTS = ('m4a', ) # files to convert to lossy format
LINK_EXTS = ('mp3', ) # files to link instead of convert
for root, dirs, files in os.walk(UNCOMPRESSED_DIR):
out_root = COMPRESSED + root
if not os.path.exists(out_root):
os.mkdir(out_root)
for file in files:
file_path = os.path.join(root, file)
file_root, ext = os.path.splitext(file_path)
if ext[1:] in LINK_EXTS:
if not os.path.exists(COMPRESSED + file_path):
print('Linking {}'.format(file_path))
link_source = os.path.relpath(file_path, out_root)
os.symlink(link_source, COMPRESSED + file_path)
continue
if ext[1:] not in UNCOMPRESSED_EXTS:
print('Skipping {}'.format(file_path))
continue
out_file_path = COMPRESSED + file_path
if (os.path.exists(out_file_path)
and os.path.getctime(out_file_path) > os.path.getctime(file_path)):
print('Up to date: {}'.format(file_path))
continue
print('Converting {}'.format(file_path))
subprocess.call(['ffmpeg', '-y', '-i', file_path,
'-c:a', 'libfdk_aac', '-vbr', '4',
out_file_path])
もちろん、これはエンコードを並行して実行するように拡張できます。それは読者への演習として残されています;-)
Bash 4.xを使用している場合は、 新しいグロビングオプション を使用できます。例:
Shell:=/bin/bash -O globstar
list:
@echo Flac: $(Shell ls flac/**/*.flac)
@echo MP3: $(Shell ls mp3/**/*.mp3)
この種の再帰的なワイルドカードは、関心のあるすべてのファイルを見つけることができます(。flac、。mp3または何でも)。 O