あなたが持っているものはかなり良いです、あなたはかなり近いです。
私がテストしていた環境で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ツリーの破損を上書きするために使用)
フィルタが、、またはの場合newdirs
、newfiles
2all
番目のパラメータを使用して、ディレクトリ名をさらにフィルタリングできます。*と?を使用できます ファイルのセットに一致するワイルドカード文字。
スクリプトを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
幸運を。これがお役に立てば幸いです。