mysql - 加速 Bash ID3 到 MySQL 的导入

标签 mysql linux bash shell id3

我有 2 个 Bash 脚本通过一个目录,从 MP3 中提取 ID3 信息,并将标签信息导入 MySQL 数据库。完成运行需要很长时间,所以我希望有人能帮助我使脚本更有效率。

脚本如下:

makeid3dbentry.sh

TRACK=$(id3info "$1" | grep '^=== TIT2' | sed -e 's/.*: //g')
ARTIST=$(id3info "$1" | grep '^=== TPE1' | sed -e 's/.*: //g')
ALBUM=$(id3info "$1" | grep '^=== TALB' | sed -e 's/.*: //g')
ALBUMARTIST=$(id3info "$1" | grep '^=== TPE2' | sed -e 's/.*: //g')

COLS='`artist`,`name`,`album`,`albumartist`,`filename`'
# Replace all: ${string//substring/replacement} to escape "
VALS='"'${ARTIST//\"/\\\"}'","'${TRACK//\"/\\\"}'","'${ALBUM//\"/\\\"}'","'${ALBUMARTIST//\"/\\\"}'","'${1}'"'

SETLIST='`artist`="'${ARTIST//\"/\\\"}'",`name`="'${TRACK//\"/\\\"}'",`album`="'${ALBUM//\"/\\\"}'",`albumartist`="'${ALBUMARTIST//\"/\\\"}'",`filename`="'${1}'"'

echo 'INSERT INTO `music` ('${COLS}') VALUES ('${VALS}') ON DUPLICATE KEY UPDATE '${SETLIST}';'
exit

这会产生一个 INSERT 语句,例如

INSERT INTO `music` (`artist`,`name`,`album`,`albumartist`,`filename`) VALUES ("1200 Micrograms","Ayahuasca","1200 Micrograms","1200 Micrograms","/mnt/sharedmedia/music/Albums/1200 Micrograms/1200 Micrograms [2002]/1-01 - 1200 Micrograms - Ayahuasca.mp3") ON DUPLICATE KEY UPDATE `artist`="1200 Micrograms",`name`="Ayahuasca",`album`="1200 Micrograms",`albumartist`="1200 Micrograms",`filename`="/mnt/sharedmedia/music/Albums/1200 Micrograms/1200 Micrograms [2002]/1-01 - 1200 Micrograms - Ayahuasca.mp3";

然后从主更新脚本调用:

更新音乐数据库.sh

DIRFULLPATH="${1}"
DIRECTORY=$(basename "${DIRFULLPATH}")

SQLFILE="/var/www/html/scripts/sql/rebuilddb_${DIRECTORY}.sql"
find "${DIRFULLPATH}" -type f -iname "*.mp3" -exec /var/www/html/scripts/bash/makeid3dbentry.sh {} > "${SQLFILE}" \;
mysql --defaults-extra-file=/var/www/html/config/website.cnf --default-character-set=utf8 "website" < "${SQLFILE}"

不幸的是,我不太了解 Bash 和 Linux 环境,无法了解瓶颈在哪里以及如何改进这些脚本。我将不胜感激关于改进脚本的任何建议,如果它更好/更快,甚至是不同的方法。

最佳答案

您可以按照评论中的建议避免多次运行 id3info

您还可以使 makeid3dbentry.sh 在您的代码周围使用一个简单的 for file in "${@}" 获取多个参数。然后您可以使用 -exec yourscript.sh {} + 运行 find(类似于 xargs)。这样您就可以大大减少脚本的调用次数。不过,我可能会建议将整个事情作为一个脚本来完成。您可以使用 find 命令(不带 -exec 参数)将插入语句生成包装在 for 循环中,并将此输出通过管道传输到文件。

假设您的 MySQL 数据库正在使用 InnoDB,您可以通过告诉 MySQL 在作业完成之前跳过提交数据(而不是在每次插入时都这样做)来加快插入速度。 在 SQLFILE 的顶部插入 START TRANSACTION;,在底部插入 COMMIT;。 参见 http://dev.mysql.com/doc/refman/5.6/en/commit.html , http://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html

关于mysql - 加速 Bash ID3 到 MySQL 的导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26266304/

相关文章:

MySQL从十进制转换为字符串

mysql - 如何做多个封装的WHERE子句

mysql - 如果右字段存在,左连接如何使用

c - 使用程序名称查找进程 ID

linux - 如何从VM oracle enterprise linux访问主机文件

linux - 当 bash 中的命令之间使用 & 符号时重定向 stdout 和 stderr

SQL:优化 DateTime 字段上的密集 SELECT

c - 实时感知 sleep() 调用?

bash - 如何创建一个 bash 环境变量,在命令之前添加环境变量前缀?

bash - 在 Bash 中按字母顺序排序