繁体   English   中英

通过遍历子目录自动将WAV文件转换为MP3的批处理脚本

[英]Batch Script for conversion of WAV files to MP3 automatically by traversing through sub-directories

编辑1

步骤1:电话交谈以.WAV格式记录在特定的文件夹和子文件夹中(由语音记录软件自动创建,当前日期格式为20121119(YYYYMMDD) 。此命名约定无法更改。子文件夹是在D驱动器RECFILED文件夹中自动创建的, 例如 ,如果今天录制的文件将存储在20121119子文件夹中,而昨天的文件存储在20121118中

步骤2:最终,这些* .WAV文件需要转换为* .MP3格式并上传到Amazon S3。 目前,此过程是手动的。 既然有很多WAV文件,所以我使用SOX将WAV批量转换为MP3。 为此,我创建了一个批处理文件(在原始问题中进行了解释),以便可以自动执行此转换过程。 此批处理文件将WAV转换为MP3,并将MP3文件与WAV文件保存在同一文件夹中。 为此,我要做的是将批处理文件复制到文件夹中并运行它。 它将转换文件并将其保存在同一文件夹中。

步骤3:文件转换后。 然后在Amazon S3的特定存储桶中,我必须创建一个具有当前日期的新文件夹,以便所有这些MP3都可以存储在该文件夹中。 但是,此处的日期格式为DD.MM.YYYY 文件夹层次结构为\\ BucketName \\ Voice \\ 201211 \\ 19.11.2012 \\ *。MP3(适用于今天)\\ BucketName \\ Voice \\ 201211 \\ 20.11.2012 \\ *。MP3(适用于明天)等。

现在,问题是:

  1. 遍历到最新文件夹(查看d:\\ RecFileD \\ YYYYMMDD),然后查看该文件夹中是否有WAV文件。 如果是,请将这些文件转换为MP3并将其存储在任何特定位置的本地服务器上名为DD.MM.YYYY的文件夹中。 (今天的日期,但格式不同)。

  2. 一次,创建文件夹(使用DD.MM.YYYY命名约定。同一文件夹需要在特定月份(即201211)上上传到S3。一旦月份更改(例如12月),则与12月份有关的文件将放在文件夹201212中,依此类推。

  3. 这里的问题是,在本地服务器上,命名约定为YYYYMMDD(不带空格,点或逗号),在S3上,命名约定为DD.MM.YYYY(带点)。

原始问题

请帮我写一个批处理文件,以便我可以自动将WAV文件转换为MP3,然后将它们直接上传到Amazon S3到特定文件夹。 现在这是一个手动过程。

事实上,我们正在运行一个小型呼叫中心,所有的语音通话记录和保存在服务器上的D:推动命名的文件夹RecFileD ,并用当前日期命名的子文件夹(例如, 2012111720121116等)。 默认情况下,文件以WAV格式保存。 我需要先将文件转换为MP3,然后再将其上传到Amazon S3进行存储。

要求是我需要在一天的特定时间每天在S3上载MP3文件。 问题是如何遍历最后一个文件夹(当前日期文件夹)并转换文件。 在本地服务器上,语音文件保存在d:\\RecFileD\\20121117\\*.wav ,在Amazon S3上,这些文件上传到以下文件夹中:

  • \\BucketName\\Voice\\201211\\17.11.2012\\*.mp3 (用于11月);

  • \\bucketName\\Voice\\201212\\01.12.2012\\*.mp3 (适用于12月)( \\bucketName\\Voice\\201212\\01.12.2012\\*.mp3 31个文件夹)。

为了自动进行转换,我创建了以下批处理文件。 该文件使用SOX应用程序将WAV文件转换为当前文件夹中的MP3。

@echo off
call :treeprocess
goto :eof

:treeprocess
for %%f in (*.wav) do 
(
  sox %%~nf.WAV %%~nf.mp3
  sox %%~nf.WAV %%~nf-short.mp3 trim 0:30 1:00
)

for /D %%d in (*) do 
(
  cd %%d
  call :treeprocess
  cd ..
)
exit /b

为了自动将文件上传到S3,我将使用S3命令行工具。

简而言之,需要执行以下步骤:

  1. 遍历当前日期的文件夹只( 201211152012111620121117本地服务器上等等)和WAV文件转换为MP3格式(使用上面的脚本)。

  2. 将这些MP3文件移动到自动创建的单独文件夹中,命名为17.11.2012 (根据当前日期)。

  3. 将文件夹上传到特定位置的Amazon S3。 \\bucketname\\voice\\201211\\17.11.2012

您所拥有的非常好,您也非常接近。

我在必需的do (上测试的环境do (将open paren与do放在同一行。中间用换行符进行格式化可能会导致问题。

您完全缺少的是对目录名称的任何解析,该解析应该是YYYYMMDD。 您可以执行以下操作:

set dirname=%%d

set year=%dirname:~0,4%
set month=%dirname:~4,2%
set day=%dirname:~6,2%

完成此操作后,可以轻松地基于YYYY,MM和DD创建文件名和路径:

set s3path=!file_year!!file_month!\!file_day!.!file_month!.!file_year!

将生成类似YYYYMM \\ DD.MM.YYYY的路径。

您可以使用以下命令获取“ last”目录:

for /f "tokens=1" %%a IN ('dir /b /a:d /o:n ????????') do (
  set dirset=%%a
)

注意:这仅在第二个解决方案中实现。 让我们分解一下:

dir /b /a:d /o:n ????????

是否使用“裸露”格式的目录(仅是匹配文件的列表,每行一个),带有属性目录(仅列表目录),按名称排序(这是NTFS上的默认设置,而不是FAT上的默认设置,因此最好指定排序顺序),匹配?????????,任意8个字符(因为目录的命名方式应为YYYYMMDD,因此始终为8个字符)。 这将返回一个包含8个字符的目录名称的有序列表。

for /f "tokens=1" %%a IN ('command') do echo %%a

执行command并逐行解析结果。 在此,将回显每个结果的第一个标记。

for /f "tokens=1" %%a IN ('dir /b /a:d /o:n ????????') do (
  set dirset=%%a
)

我们把它放在一起,看看这dirset将被设置为每个匹配的目录名。 但是在for循环完成后,它将保留为最后一个值或“最新”目录。

在下面的代码我已dirname单独设置,以避免与变量扩展规则的问题。 或者,您应该可以使用:

setlocal enableextensions enabledelayedexpansion 

set dirname=%%d
set year=!dirname:~0,4!

如上所述,您的问题不需要递归。 我的代码只是迭代每个目录,然后迭代每个文件。 如果文件布局的结构性较差,则说明您需要进行递归。

您没有指定要使用的Windows S3命令行工具,所以我用本地完整路径和局部路径回显*S3COPY* 您应该可以使用copy命令替换它。

您需要从d:\\RecFileD运行此d:\\RecFileD ,也可以将其添加到bat文件顶部附近:

d:
cd \RecFileD

您可能需要将s3root更改为本地S3副本的实际根目录。 我没有移动文件,而是用sox在正确的位置创建它们。

我设置年,月,日瓦尔在processfiles因为在设置它们processdirs由变量扩展规则复杂。

如果您要做的还不止这些,我建议您研究Python。 它有一个很棒的社区/生态系统,易于上手并且免费。 另外,您不会花费所有时间与语言进行战斗。

这是我的第一次尝试:

@echo off

setlocal

set s3root=d:\s3\bucket\voice

call :processdirs
goto :eof

:processfiles
  set year=%dirname:~0,4%
  set month=%dirname:~4,2%
  set day=%dirname:~6,2%

  set s3path=%year%%month%\%day%.%month%.%year%
  set s3dir=%s3root%\%s3path%
  if not exist "%s3dir%" md "%s3dir%"

  for %%f in (*.wav) do (
    sox "%%~nf.WAV" "%s3dir%\%%~nf.mp3"
    sox "%%~nf.WAV" "%s3dir%\%%~nf-short.mp3" trim 0:30 1:00
  )

  echo *S3COPY* %s3dir% %s3path%
  goto :eof

:processdirs
  for /D %%d in (*) do (
    set dirname=%%d
    cd "%%d"
    call :processfiles
    cd ..
  )
  goto :eof

@Aacini的答案使我意识到,不幸的是我缺乏解决方案。 它不只处理今天的文件。 但是我担心跳过一天会发生什么。

我添加了两个参数来控制要处理的内容。 第一个参数指定一个命名过滤器,可以是以下其中一个:

  • newlatest-最新目录中的新文件,基于文件名(默认)
  • 最新 -基于文件名的最新目录中的所有文件
  • 今天 -今天的目录
  • newdirs -S3树中不存在的所有目录(缺少日期)
  • newfiles -S3树中不存在的所有文件
  • all-所有文件(用于覆盖S3树中的损坏)

如果过滤器是newdirsnewfilesall ,则可以使用第二个参数进一步过滤目录名称。 您可以使用*和? 通配符以匹配一组文件。

如果将脚本另存为ProcDirs.bat,则以下是一些示例:

ProcDirs all 20121119
将强制处理(或重新处理)指定的目录。

ProcDirs newdirs 201211??
将处理与目录名称(指定年份和月份的任何一天)匹配的新目录(缺少输出树)。

ProcDirs newfiles 2012????
将在目录名称(指定年份的任意一天)匹配的目录中处理新文件(缺少输出树)。

ProcDirs
ProcDirs newlatest
完全一样,因为newlatest是默认设置。 这将处理(按词法)“最新”目录中的新文件

代码更复杂,但也不太糟糕 我确实尝试使用@Aacini的代码来获取今天的月/日/年,但这在我的系统上不起作用(因为我的日期格式必须与要求的日期格式不同)。 因此,我使用了一种不依赖于本地日期格式的不同方法。

我的第一个解决方案不需要延迟的扩展,但是我需要使用setlocal打开它(可以在Win XP上运行,但可能不适用于较旧的Windows)并使用! 而不是%来代替环境变量。

@echo off

setlocal enableextensions enabledelayedexpansion

set s3root=d:\s3\bucket\voice

rem Set the default filter mode

set newfilter=none
set dirsetfilter=none

set arg=%1
if "!arg!" == "" set arg=newlatest

if "!arg!" == "newdirs" (
  set newfilter=newdirs
) else if "!arg!" == "newfiles" (
  set newfilter=newfiles
) else if "!arg!" == "all" (
  set dirsetfilter=none
  set newfilter=none
) else if "!arg!" == "today" (
  set dirsetfilter=today
) else if "!arg!" == "latest" (
  set dirsetfilter=latest
) else if "!arg!" == "newlatest" (
  set newfilter=newfiles
  set dirsetfilter=latest
)

if !dirsetfilter! == today (
  for /f "skip=1 tokens=1-3" %%a IN ('wmic path Win32_LocalTime Get Day^,Month^,Year /Format:table') do (
    if %%a GTR 0 (
      set now_day=%%a
      set now_month=%%b
      set now_year=%%c
    )
  )
  set dirset=!now_year!!now_month!!now_day!
  if not "%2" == "" echo Second parameter, dirset, ignored when filter is today
) else if !dirsetfilter! == latest (
  rem pull out the name of the 'last' directory
  for /f "tokens=1" %%a IN ('dir /b /a:d /o:n ????????') do (
    set dirset=%%a
  )
  if not "%2" == "" echo Second parameter, dirset, ignored when filter is latest
) else if not "%2" == "" (
  rem The second parameter is dirset. Wild card chars, *? allowed
  rem only matched dir(s) processed
  set dirset=%2
) else (
  rem process all dirs that match filter
  set dirset=*
)

call :processdirs
goto :eof

:processfiles
  set file_year=!dirname:~0,4!
  set file_month=!dirname:~4,2!
  set file_day=!dirname:~6,2!

  set s3path=!file_year!!file_month!\!file_day!.!file_month!.!file_year!
  set s3dir=!s3root!\!s3path!

  set skipdir=FALSE
  if not exist "!s3dir!" (
    md "!s3dir!"
  ) else (
    if newdirs == !newfilter! set skipdir=TRUE
  )

  if !skipdir! == FALSE (
    set havenewfiles=FALSE

    for %%f in (*.wav) do (
      set skipfile=FALSE
      if newfiles==!newfilter! if exist "!s3dir!\%%~nf.mp3" set skipfile=TRUE
      if !skipfile! == FALSE (
        set havenewfiles=TRUE
        echo sox "%%~nf.WAV" "!s3dir!\%%~nf.mp3"
        sox "%%~nf.WAV" "!s3dir!\%%~nf.mp3"
      )

      set skipfile=FALSE
      if newfiles == !newfilter! if exist "!s3dir!\%%~nf-short.mp3" set skipfile=TRUE
      if !skipfile! == FALSE (
        set havenewfiles=TRUE
        echo sox "%%~nf.WAV" "!s3dir!\%%~nf-short.mp3" trim 0:30 1:00
        sox "%%~nf.WAV" "!s3dir!\%%~nf-short.mp3" trim 0:30 1:00
      )
    )

    if !havenewfiles! == TRUE (
      echo *S3COPY* !s3dir! !s3path!
    )
  )
  goto :eof

:processdirs
  for /D %%d in (!dirset!) do (
    echo Process Dir: %%d
    set dirname=%%d
    cd "%%d"
    call :processfiles
    cd ..
  )
  goto :eof

祝好运。 我希望这有帮助。

哇! 听起来比实际要复杂得多!

@echo off
rem Create folder names from current date, MM/DD/YYYY locale format is assumed
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
   set YYYYMMDD=%%c%%a%%b
   set YYYYMM=%%c%%a
   set DD.MM.YYYY=%%b.%%a.%%c
)
rem Enter into target folder
cd /D D:\RecFileD\%YYYYMMDD%
rem Convert WAV files to MP3 using SOX
for %%f in (*.wav) do (
   sox %%~nf.WAV %%~nf.mp3
   sox %%~nf.WAV %%~nf-short.mp3 trim 0:30 1:00
)
rem Move MP3 files to brother folder
md ..\%DD.MM.YYYY%
move *.mp3 ..\%DD.MM.YYYY%
rem Upload the folder to Amazon S3
echo S3COPY from ..\%DD.MM.YYYY% to \bucketname\voice\%YYYYMM%\%DD.MM.YYYY%

我建议您在描述问题时尽可能简洁,但不要忘记任何细节。 例如,在您的(长篇)描述中,对名为17.11.2012的本地文件夹的解释还不够!

我希望这就是你想要的...

安东尼奥

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM