CMD:提取文件名的一部分并将其用作变量

时间:2015-01-11 13:13:21

标签: variables batch-file extract

我用EAC将我的CD撕成了CUE + WAV文件,添加了封面图片,所有文件都在文件名模式“专辑艺术家 - 专辑标题”的同一个文件夹中,例如:

Clannad - Legend.wav/cue/jpg
David Bowie - Best Of Bowie [Disc 1].wav/cue/jpg
David Bowie - Best Of Bowie [Disc 2].wav/cue/jpg

我是新手,所以我写了一个简单的CMD批量转换我的音乐到FLAC格式,但它需要手动复制和粘贴实际的wav / cue / jpg文件名和专辑艺术家的输入,光盘号码。并且总盘数没有。对于他们相应的标签。由于某种原因,它不能存储在cuesheet文件中,但在我的情况下,我将它们放在文件名中,如上所示。)

ECHO WAV/CUE/JPG FILENAME
SET /P "input="
ECHO ALBUMARTIST
SET /P "albumartist="
ECHO DISCNUMBER
SET /P "discnumber="
ECHO TOTALDISCS
SET /P "totaldiscs="

flac.exe -0 --picture="D:\Music\%input%.jpg" --tag-from-file="CUESHEET=D:\Music\%input%.cue" -T "ALBUMARTIST=%albumartist%" -T "DISCNUMBER=%discnumber%" -T "TOTALDISCS=%totaldiscs%" "D:\Music\%input%.wav"

我的问题是关于转换所有翻录相册的自动化。如何提取专辑艺术家/光盘号码/全盘光盘号码。每个.wav文件的文件名和循环信息?

2 个答案:

答案 0 :(得分:1)

@ECHO OFF
SETLOCAL
SET "destdir=U:\destdir"
PUSHD "%destdir%"
:: Find all .jpgs where there is a .wav and .cue with the same name
FOR /f "delims=" %%a IN ('dir /b /a-d *.jpg') DO IF EXIST "%%~na.wav" IF EXIST "%%~na.cue" (
 FOR %%b IN (input albumartist discnumber totaldiscs) DO SET "%%b="
 SET "input=%%~na"
 FOR /f "delims=-" %%b IN ("%%a") DO SET "albumartist=%%b"
 FOR /f "tokens=2delims=[]" %%b IN ("%%a") DO SET "disc=%%b"
 IF DEFINED disc (
  FOR /f "tokens=1delims=[]" %%d IN ("%%a") DO FOR /f %%c IN ('dir /b "%%d[*.wav"') DO SET /a totaldiscs+=1
 )
 CALL :gflac
)

POPD

GOTO :EOF

:gflac
:: remove trailing spaces from INPUT
IF "%albumartist:~-1%"==" " SET "albumartist=%albumartist:~0,-1%"&GOTO gflac
:: presume default for disc and totaldiscs
IF DEFINED disc (FOR /f "tokens=2" %%d IN ("%disc%") DO SET /a disc=%%d) ELSE (SET /a disc=1)
IF NOT DEFINED totaldiscs SET /a totaldiscs=1
ECHO( flac.exe -0 --picture="D:\Music\%input%.jpg" --tag-from-file="CUESHEET=D:\Music\%input%.cue" -T "ALBUMARTIST=%albumartist%" -T "DISCNUMBER=%discnumber%" -T "TOTALDISCS=%totaldiscs%" "D:\Music\%input%.wav"
GOTO :eof

您需要更改destdir的设置以适合您的具体情况。

以上只会echo所需的flac行。我在你发布的时候把它留下了,但是当我在U:驱动器上解释它(即有一组3个文件)时,你设置了很少的测试数据。

可悲的是,您给我们的信息不足。我假设您需要存在所有三个文件,totaldiscs的默认值为1.

首先,查找所有.jpgs,如果有相应的.wav.cue,请按以下步骤处理flac代:

  • input设置为.jpg找到的
  • 的名称部分
  • albumartist设置为文件名的第一部分,直至-
  • 获取[disc n]字符串(如果它出现
  • 计算以.wav
  • 开头的[ s的数量
  • 生成flac行。

flac行的生成过程中,我们从input剥离尾随空格,将disc n转换为n或将光盘设置为1(尽管此信息可能如果没有计算,则将totaldiscs设置为1。

你不能说出flac作为输出产生的内容,但我建议您进一步选择该文件类型,以便在%input%.finalproductwhateverthatis {}}}时无法运行该程序文件存在。

[根据dbenham编辑评论]

答案 1 :(得分:0)

这与Magoo的答案非常相似,有一些错误修复,所有内容都在没有CALL的一个主循环中完成。与Magoo的答案一样,请在开头修改目标文件夹以满足您的需求。

@echo off
:: Delayed expansion must be disabled to protect ! when expanding FOR variables.
:: It is normally disabled by default, but I'm making it explicit, just to be sure.
setlocal disableDelayedExpansion

:: Define where source files are coming from
set "source=D:\Music"

:: Define where output should be stored
set "destination=D:\Music"

pushd "%destination%"

:: Iterate each .wav file (A) and only proceed if .jpg and .cue also exists
for /f "delims=" %%A in ('dir /b /a-d "%source%\*.wav"') do if exist "%source%\%%~nA.jpg" if exist "%source%\%%~nA.cue" (

  %= Get base name with path, but without extension =%
  set "file=%source%\%%~nA"

  %= Extract "artist - album " (B) and "Disc #" (C) from base name (~nA) =%
  for /f "delims=[] tokens=1,2" %%B in ("%%~nA") do (

    %= Extract "artst " (D) from "artist - abum ". (~nxD) trims trailing space =%
    for /f "delims=-" %%D in ("%%B") do set "artist=%%~nxD"

    %= Extract the number (E) from "Disc #", use 1 as default if not there =%
    set "disc=1"
    for /f "tokens=2" %%E in ("%%C") do set "disc=%%E"

    %= Count the number of discs (F), will be 0 if no [Disc #] =%
    %= The [ is appended to name to prevent something like "Greatest Hits 2" from matching "Greatist Hits" =%
    for /f %%F in ('dir /b /a-d "%source%\%%B[*.wav" 2^>nul ^|find /c /v ""') do set "count=%%F"

    %= temporarily enable delayed expansion to access variables set within loop =%
    setlocal enableDelayedExpansion

    %= Set count to 1 if no [Disc #] =%
    if !count! equ 0 set /a count=1

    flac.exe -0 --picture="!file!.jpg" --tag-from-file="CUESHEET=!file!.cue" -T "ALBUMARTIST=!artist!" -T "DISCNUMBER=!disc!" -T "TOTALDISCS=!count!" "!file!.wav"

    %= pop the setlocal stack to get back to state at beginning of loop =%
    endlocal
  )
)
popd

您可能希望添加检查以仅在FLAC文件尚不存在时继续,以便您可以多次运行脚本而无需重新处理文件。外部循环看起来像这样,但我不能确定,因为我不知道输出文件名的格式:

for /f "delims=" %%A in ('dir /b /a-d "%source%\*.wav"') do if exist "%source%\%%~nA.jpg" if exist "%source%\%%~nA.cue" if not exist "%destination%\%%~nA.flac" (

如果你理解正则表达式,那么使用我的JREPL.BAT utility逻辑要简单得多:

@echo off
:: Delayed expansion must be disabled to protect ! when expanding FOR variables.
:: It is normally disabled by default, but I'm making it explicit, just to be sure.
setlocal disableDelayedExpansion

:: Define where source files are coming from
set "source=D:\music"

:: Define where output should be stored
set "destination=D:\music"

pushd "%destination%"


:: Iterate all *.wav and use JREPL to format result as "fullFileName|artist - album|artist|Disc#"
::                                                      %%A          %%B            %%C    %%D
:: Only proceed if .jpg and .cue also exist
for /f "tokens=1-4 delims=|" %%A in (
  'dir /b /a-d "%source%\*.wav"^|jrepl "^((.+?) - .+?)(?:\[Disc (\d+)])?\.wav$" "$&|$1|$2|$3" /i'
) do if exist "%%~nA.jpg" if exist "%%~nA.cue" (

  %= disc and count are both 1 if %%D is empty =%
  if "%%D" equ "" (
    flac.exe -0 --picture="%source%\%%~nA.jpg" --tag-from-file="CUESHEET=%source%\%%~nA.cue" -T "ALBUMARTIST=%%C" -T "DISCNUMBER=1" -T "TOTALDISCS=1" "%source%\%%A"

  %= else count the number of .wav files =%
  ) else for /f %%E in ('dir /b /a-d "%%B[*.wav"^|find /c /v ""') do (
    flac.exe -0 --picture="%source%\%%~nA.jpg" --tag-from-file="CUESHEET=%source%\%%~nA.cue" -T "ALBUMARTIST=%%C" -T "DISCNUMBER=%%D" -T "TOTALDISCS=%%E" "%source%\%%A"
  )
)

popd

同样,只有当目标中不存在.flac文件时,才可以向外部循环添加IF以继续。