1

編集1

ステップ 1: 電話での会話は、特定のフォルダーとサブフォルダー (音声録音ソフトウェアによって現在の日付形式、つまり20121119 (YYYYMMDD)で自動的に作成される) に .WAV 形式で記録されます。この命名規則は変更できません。現在の日付D ドライブのRECFILEDというフォルダにサブフォルダが自動的に作成されます. たとえば、今日の録音の場合、ファイルは20121119サブフォルダに格納され、昨日のファイルは20121118に格納されます.

ステップ 2: 1 日の終わりに、これらの *.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:フォルダー内のドライブのサーバーに保存されます。デフォルトでは、ファイルは WAV 形式で保存されます。ストレージ用に Amazon S3 にアップロードする前に、ファイルを MP3 に変換する必要があります。RecFileD2012111720121116

要件は、1 日の終わりの特定の時間に S3 に MP3 ファイルを毎日アップロードする必要があることです。問題は、最後のフォルダー (現在の日付フォルダー) にトラバースしてファイルを変換する方法です。ローカル サーバーでは、音声ファイルはd:\RecFileD\20121117\*.wavAmazon S3 に保存され、ファイルはフォルダーにアップロードされます。

  • \BucketName\Voice\201211\17.11.2012\*.mp3(これは 11 月のものです);

  • \bucketName\Voice\201212\01.12.2012\*.mp3(これは 12 月の場合です) (すべての日で 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. ローカル サーバー上の現在の日付フォルダーのみ ( 、 など) にトラバースし2012111520121116WAV20121117ファイルを MP3 に変換します (上記のスクリプトを使用)。

  2. これらの MP3 ファイルを、17.11.2012(現在の日付に従って) という名前で自動的に作成された別のフォルダーに移動します。

  3. フォルダを特定の場所の Amazon S3 にアップロードします。すなわち、\bucketname\voice\201211\17.11.2012

4

2 に答える 2

0

あなたが持っているものはかなり良いです、あなたはかなり近いです。

私がテストしていた環境で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のようなパスを生成します。

次を使用して「最後の」ディレクトリを取得できます。

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

注:これは、2番目のソリューションでのみ実装されます。これを分解してみましょう:

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

'bare'形式のディレクトリ(一致するファイルのリストのみ、1行に1つ)、属性ディレクトリ(ディレクトリのリストのみ)、名前による順序(これは、NTFSではデフォルトですが、FATではないため、並べ替え順序を指定するのが最適です) )、一致する????????、任意の8文字(ディレクトリはYYYYMMDDのように名前が付けられると予想されるため、常に8文字)。これにより、8文字のディレクトリ名の順序付きリストが返されます。

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

を実行commandし、結果を1行ずつ解析します。ここでは、各結果の最初のトークンがエコーされます。

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!

述べたように、あなたの問題は再帰を必要としません。私のコードは、各ディレクトリを繰り返してから、各ファイルを繰り返します。ファイルレイアウトがあまり構造化されていない場合は、指定すると、再帰が必要になることがあります。

使用するWindowsS3コマンドラインツールを指定しなかったため*S3COPY*、ローカルのフルパスとパーシャルパスでエコーします。これをコピーコマンドに置き換えることができるはずです。

これをから実行する必要があります。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の回答は私に気づかせました、残念ながら私の解決策は欠けています。今日のファイルだけを処理するわけではありません。しかし、私は1日がスキップされたときに何が起こるかについて心配しています。

何を処理するかを制御するために2つのパラメーターを追加しました。最初のパラメーターは名前付きフィルターを指定し、次のいずれかになります。

  • newlatest-ファイル名に基づく最新のディレクトリ内の新しいファイル(デフォルト)
  • last-ファイル名に基づく、最新のディレクトリ内のすべてのファイル
  • 今日-今日のディレクトリ
  • newdirs -S3ツリーに存在しないすべてのdir(欠落している日付)
  • newfiles -S3ツリーに存在しないすべてのファイル
  • all-すべてのファイル(S3ツリーの破損を上書きするために使用)

フィルタが、、またはの場合newdirsnewfiles2all番目のパラメータを使用して、ディレクトリ名をさらにフィルタリングできます。*と?を使用できます ファイルのセットに一致するワイルドカード文字。

スクリプトをProcDirs.batとして保存する場合、次にいくつかの例を示します。

ProcDirs all 20121119
指定されたディレクトリの処理(または再処理)を強制します。

ProcDirs newdirs 201211??
ディレクトリ名(指定された年月の任意の日)に一致する新しいディレクトリ(出力ツリーにない)を処理します。

ProcDirs newfiles 2012????
dir名(指定された年の任意の日)に一致するディレクトリ内の新しいファイル(出力ツリーにない)を処理します。

ProcDirs
ProcDirs newlatest
newlatestがデフォルトである ため、まったく同じです。これにより、(字句的に)'latest'ディレクトリ内の新しいファイルが処理されます

コードはもっと複雑ですが、それほど悪くはありません。@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

幸運を。これがお役に立てば幸いです。

于 2012-11-17T20:50:40.603 に答える
0

わお!このサウンドは、実際よりもはるかに複雑です。

@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が十分に説明されていません。

これがあなたが望んでいたものであることを願っています...

アントニオ

于 2012-11-17T22:17:14.733 に答える