批处理修改无损音乐的cue文件内容

原文链接:http://www.newsmth.net/nForum/article/DOS/21969?s=21969

今天一水木网友把8年多前的一篇帖子翻出来,发信给我说代码有bug!?难道没看过下面这个段子么!

千万不要跟程序猿说:你的代码有bug。
他的第一反应是你的环境有问题,第二就是你是傻逼不会用吧。
你要跟他这么说:这个程序怎么运行的跟预期不一样,是我操作有问题吗?
程序猿就会第一反应:我擦,这是不是出bug了?

刚好迁移了新博客,把内容转过来写吧。

1
2
3
4
5
6
7
8
9
10
11
发信人: coreqq (风起云涌), 信区: DOS
标 题: 问个复杂点的批处理
发信站: 水木社区 (Mon Jan 4 23:12:37 2010), 站内

两个文件a.txt,b.txt

a中含有如“01.字符串1”“02.字符串2”之类条目(一条一行)
b中有"title01""title02"之类条目(一条一行)
现在需要把b中的“title01”用a中的“字符串1”替换,“title02”用“字符串2”换,…

请问如何写?

以下代码保存为批处理文件,比如 convert-cue.bat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@echo off
::Code by oicu#lsxk.org 2010-01-05, for cmd@Windows

type nul>c.txt
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "delims=" %%a in (b.txt) do (
echo.%%a | findstr /i "Track[0-9]" >NUL && (
set swap=%%a
set swap=!swap:Track=!
FOR /F "tokens=1,2* delims=." %%i in ('type a.txt^| findstr /i "!swap!"') do (
echo. TITLE "%%j">>c.txt
)
) || (
echo.%%a>>c.txt
)
)
ENDLOCAL
goto :eof

翻看了以前的代码,虽然结果无误,觉得还是有必要优化一下避免特例情况出错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@echo off
::Code by oicu#lsxk.org 2018-10-11, for cmd@Windows

type nul>c.txt
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "delims=" %%a in (b.txt) do (
echo.%%a | findstr /i "Track[0-9]" >NUL && (
set swap=%%a
set swap=!swap:Track=!
rem 因为截取方式不准确,还是使用替换,直到得到2位数字
set swap=!swap:TITLE=!
set swap=!swap:"=!
set swap=!swap: =!
rem 搜索时,在行首搜索数字并带点,比如 01.
FOR /F "tokens=1,2* delims=." %%i in ('type a.txt^| findstr /i "^^!swap!\."') do (
rem 根据实际情况调整缩进的空格
echo. TITLE "%%j">>c.txt
)
) || (
echo.%%a>>c.txt
)
)
ENDLOCAL
goto :eof

以下就用水木网友 javame 提供的内容做示例。

清单 a.txt 如下,不要有空行等多余的无关信息

1
2
3
4
5
6
7
8
9
10
01.成长的岁月
02.流不完的泪
03.愿你莫忘记
04.飘往山那边
05.岁月的歌
06.应该不应该
07.分手
08.梦儿难忘记
09.请你别忘记
10.舞女

原 cue 文件内容 b.txt 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
REM DISCID 8308500A
REM COMMENT "ExactAudioCopy v0.99pb5"
PERFORMER "龙飘飘"
TITLE "最好的龙飘飘CD2"
FILE "CDImage2.wav" WAVE
TRACK 01 AUDIO
TITLE "Track01"
PERFORMER "龙飘飘"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "Track02"
PERFORMER "龙飘飘"
INDEX 01 03:55:10
TRACK 03 AUDIO
TITLE "Track03"
PERFORMER "龙飘飘"
INDEX 01 08:14:13
TRACK 04 AUDIO
TITLE "Track04"
PERFORMER "龙飘飘"
INDEX 01 11:41:03
TRACK 05 AUDIO
TITLE "Track05"
PERFORMER "龙飘飘"
INDEX 01 14:25:74
TRACK 06 AUDIO
TITLE "Track06"
PERFORMER "龙飘飘"
INDEX 01 18:40:71
TRACK 07 AUDIO
TITLE "Track07"
PERFORMER "龙飘飘"
INDEX 01 22:22:41
TRACK 08 AUDIO
TITLE "Track08"
PERFORMER "龙飘飘"
INDEX 01 25:55:18
TRACK 09 AUDIO
TITLE "Track09"
PERFORMER "龙飘飘"
INDEX 01 28:47:45
TRACK 10 AUDIO
TITLE "Track10"
PERFORMER "龙飘飘"
INDEX 01 31:49:61

执行批处理后,得到新的文件 c.txt,注意 TITLE 都已经替换了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
REM DISCID 8308500A
REM COMMENT "ExactAudioCopy v0.99pb5"
PERFORMER "龙飘飘"
TITLE "最好的龙飘飘CD2"
FILE "CDImage2.wav" WAVE
TRACK 01 AUDIO
TITLE "成长的岁月"
PERFORMER "龙飘飘"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "流不完的泪"
PERFORMER "龙飘飘"
INDEX 01 03:55:10
TRACK 03 AUDIO
TITLE "愿你莫忘记"
PERFORMER "龙飘飘"
INDEX 01 08:14:13
TRACK 04 AUDIO
TITLE "飘往山那边"
PERFORMER "龙飘飘"
INDEX 01 11:41:03
TRACK 05 AUDIO
TITLE "岁月的歌"
PERFORMER "龙飘飘"
INDEX 01 14:25:74
TRACK 06 AUDIO
TITLE "应该不应该"
PERFORMER "龙飘飘"
INDEX 01 18:40:71
TRACK 07 AUDIO
TITLE "分手"
PERFORMER "龙飘飘"
INDEX 01 22:22:41
TRACK 08 AUDIO
TITLE "梦儿难忘记"
PERFORMER "龙飘飘"
INDEX 01 25:55:18
TRACK 09 AUDIO
TITLE "请你别忘记"
PERFORMER "龙飘飘"
INDEX 01 28:47:45
TRACK 10 AUDIO
TITLE "舞女"
PERFORMER "龙飘飘"
INDEX 01 31:49:61

实在看不下多年前的批处理版本,最后再写个 Shell 版本,直接修改 b.txt 不生成 c.txt

1
2
3
4
5
6
#!/bin/bash
while read LINE
do
TITLE=`echo ${LINE#*.} | tr -d '\r'`
sed -i 's#TITLE "Track'${LINE%%.*}'"#TITLE "'${TITLE}'"#g' b.txt
done < a.txt