web-dev-qa-db-ja.com

ファイル名のバッチコマンドの日付と時刻

コマンドラインで WinZip を使用してファイルを圧縮しています。毎日アーカイブするため、これらのファイルに日付と時刻を追加して、毎回新しいファイルが自動生成されるようにしています。

以下を使用してファイル名を生成します。コピーしてコマンドラインに貼り付けると、日付と時刻のコンポーネントを含むファイル名が表示されます。

echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.Zip

出力

Archive_20111011_ 93609.Zip

ただし、私の問題はAMvsPMです。 AMタイムスタンプは、9(先頭に空白スペースを含む)対10が自然に2つのスペースを占める時間を提供します。

私の問題は最初の9日間、最初の9ヶ月などにも及ぶと思います。

先頭の空白スペースの代わりに先頭のゼロが含まれるようにこれを修正して、Archive_20111011_093609.Zipを取得するにはどうすればよいですか?

64
Raj More

別の解決策:

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I

(ロケール設定とは無関係に!):

  20130802203023.304000+120
( YYYYMMDDhhmmss.<milliseconds><always 000>+/-<timedifference to UTC>  )

ここからは簡単です。

set datetime=%datetime:~0,8%-%datetime:~8,6%
20130802-203023

Loganがファイルの「date-time modified」の同じ出力形式を要求する場合:

for %%F in (test.txt) do set file=%%~fF
for /f "tokens=2 delims==" %%I in ('wmic datafile where name^="%file:\=\\%" get lastmodified /format:list') do set datetime=%%I
echo %datetime%

完全なパスでのみ機能するため、少し複雑です。wmicはバックスラッシュが2倍になることを期待し、=はエスケープする必要があります(1つ目は周囲の引用符で保護されます。 )。

58
Stephan

時間を抽出し、先頭のスペースを探します。見つかった場合はゼロに置き換えます。

set hr=%time:~0,2%
if "%hr:~0,1%" equ " " set hr=0%hr:~1,1%
echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%.Zip
54
Alex K.

検索する必要があります。すべてのスペースをゼロで置き換えることができますset hr=%hr: =0%jeb10月11日14:16

だから私はやった:

set hr=%time:~0,2%
set hr=%hr: =0%

次に、フォーマットする文字列内で%hr%を使用して、常に2桁の時間を取得します。

(最も人気のある回答の下でのJebのコメントは、私にとって最もうまく機能し、最も簡単でした。将来のユーザーにわかりやすくするためにここに再投稿します。)

19
WxGuy

Vickyが既に指摘したように、%DATE%および%TIME%は、完全に(無限に)カスタマイズ可能な短い日時形式を使用して現在の日時を返します。

1人のユーザーはFri040811 08.03PMを返すようにシステムを構成し、別のユーザーは08/04/2011 20:30を選択できます。

BATプログラマーにとっては完全に悪夢です。

形式を確定形式に変更すると、BATファイルを離れる前に以前の形式に戻す場合、問題が解決する場合があります。しかし、厄介な競合状態の影響を受け、キャンセルされたBATファイルのリカバリが複雑になる可能性があります。

幸いなことに、代替手段があります。

代わりに、WMICを使用できます。 WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:tableは、日付と時刻を不変の方法で返します。 FOR /Fコマンドで直接解析すると非常に便利です。

それで、ピースを組み立てて、出発点としてこれを試してください...

SETLOCAL enabledelayedexpansion
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
  SET /A FD=%%F*1000000+%%D*100+%%A
  SET /A FT=10000+%%B*100+%%C
  SET FT=!FT:~-4!
  ECHO Archive_!FD!_!FT!.Zip
 )
15
PA.

あなたのすべての答えを読んだ後、私は私にとって最良の解決策を見つけました:

set t=%date%_%time%
set d=%t:~10,4%%t:~7,2%%t:~4,2%_%t:~15,2%%t:~18,2%%t:~21,2%
echo hello>"Archive_%d%"

AMの場合、20160915_ 150101(先頭のスペースと時間)を取得します。

PMの場合、20160915_2150101を取得します。

10
Nesar

次のように、先頭のゼロを変数(99までの値)にバッチで追加できます:IF 1%Var% LSS 100 SET Var=0%Var%

そのため、日付と時刻のコンポーネントを個別の変数に解析し、これらをすべてこのように扱い、それらを連結してファイル名を作成する必要があります。

ただし、日付と時刻を解析するための基本的な方法は、システムロケール設定に依存します。コードを他のマシンに移植できないことに満足している場合、それはおそらく大丈夫ですが、異なる国際的なコンテキストで動作することを期待する場合は、たとえばレジストリ設定を読み取るなど、異なるアプローチが必要になります:

HKEY_CURRENT_USER\Control Panel\International\iDate
HKEY_CURRENT_USER\Control Panel\International\iTime
HKEY_CURRENT_USER\Control Panel\International\iTLZero

(最後の1つは、時間に先行ゼロがあるかどうかを制御しますが、私の知る限り日付は制御しません)。

4
Vicky
@For /F "tokens=1,2,3,4 delims=/ " %%A in ('Date /t') do @(

Set DayW=%%A

Set Day=%%B

Set Month=%%C


Set Year=%%D


Set All=%%D%%B%%C
)
"C:\Windows\CWBZIP.EXE" "c:\transfer\ziptest%All%.Zip" "C:\transfer\MB5L.txt"

これはMB5L.txtを取得し、ziptest20120204.Zipに圧縮します(2012年2月4日に実行される場合)。

3
user1189773

上記の答えから、すぐに使える機能を作成しました。

フランスのローカル設定で検証済み。

:::::::: PROGRAM ::::::::::

call:genname "my file 1.txt"
echo "%newname%"
call:genname "my file 2.doc"
echo "%newname%"

echo.&pause&goto:eof
:::::::: FUNCTIONS :::::::::

:genname
    set d1=%date:~-4,4%
    set d2=%date:~-10,2%
    set d3=%date:~-7,2%
    set t1=%time:~0,2%
    ::if "%t1:~0,1%" equ " " set t1=0%t1:~1,1%
    set t1=%t1: =0%
    set t2=%time:~3,2%
    set t3=%time:~6,2%
    set filename=%~1
    set newname=%d1%%d2%%d3%_%t1%%t2%%t3%-%filename%
goto:eof
2
user2757848

あなたの質問は解決されたようですが、...

問題に対して適切な解決策を講じているかどうかはわかりません。
実際のプロジェクトコードを毎日圧縮しようとしていると思います。

Zipと1980でこれは良い解決策でしたが、今日はSubversionやgitまたは...などのリポジトリシステムを使用する必要がありますが、Zipファイルは使用しないでください。

おそらく、私が間違っている可能性があります。

1
jeb

私はこれがOPに対する議論の余地のない質問であることを理解していますが、私はこれを醸造したばかりであり、箱の外で考えることを誇りに思っています。

ダウンロード gawk Windowsの場合は http://gnuwin32.sourceforge.net/packages/gawk.htm ....それから、ライナーは1つだけで、DOSの不格好なバッチはありません構文、文字列を分割するのに6つのFORループが必要です(WTF?それは本当に悪いと悪い!...もちろん私見です)

C、C++、Perl、またはRubyを既に知っている場合は、 AWK (前の2つから継承し、後の2つに大きく貢献します)ことわざのケーキの一部!!!

DOSバッチコマンド:

echo %DATE% %TIME% && echo %DATE% %TIME% | gawk -F"[ /:.]" "{printf(""""%s%02d%02d-%02d%02d%02d\n"""", $4, $3, $2, $5, $6, $7);}"

印刷:

Tue 04/09/2012 10:40:38.25
20120904-104038

今では完全な話ではありません...私は怠laになり、printfステートメントで残りのlog-file-nameをハードコーディングします。それは簡単だからです... AWKの出力に対する%NOW%変数(「ジェネリック」機能の内臓を機能させる)がすべての耳です。


編集:

Stack Overflowをすばやく検索すると、パズルの最後の部分Bashバックティックに相当するバッチが埋められました。

したがって、DOSバッチの次の3行:

echo %DATE% %TIME% | awk -F"[ /:.]" "{printf(""""%s%02d%02d-%02d%02d%02d\n"""", $4, $3, $2, $5, $6, $7);}" >%temp%\now.txt
set /p now=<%temp%\now.txt
echo %now%

作物:

20120904-114434

そのため、SQL Serverインストール(2005+)スクリプトによって生成されたログファイルの名前に日時を含めることができます。

sqlcmd -S .\SQLEXPRESS -d MyDb -e -i MyTSqlCommands.sql >MyTSqlCommands.sql.%now%.log

そして、私は再び幸せなキャンピングカーです(ただし、Unixでの生活はずっと楽でした)。

0
corlettk

他の人が既に指摘したように、%DATE%%TIME%(およびdate /Ttime /Tの日付と時刻の形式はロケールに依存するため、現在の日付を抽出します時間は常に悪夢であり、形式の制限はほとんどないため、可能なすべての形式で動作するソリューションを取得することは不可能です。


ただし、次のようなコードには別の問題があります(MM/DD/YYYYのような日付形式とh:mm:ss.ff apのような12時間形式を想定します。ここでapAMまたはPMおよびffは秒の小数部です):

rem // Resolve AM/PM time:
set "HOUR=%TIME:~,2%"
if "%TIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%TIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %DATE:~-4,4%%DATE:~0,2%%DATE:~3,2%_%HOUR:~-2%%TIME:~3,2%%TIME:~6,2%

%DATE%および%TIME%の各インスタンスは、展開時に存在する日付または時刻の値を返すため、最初の%DATE%または%TIME%式は、次のもの(膨大な量の、好ましくは%TIME%、式を含む長い文字列をエコーするときに証明できます)。

上記のコードを改良して、次のように%DATE%および%TIME%の単一のインスタンスを保持できます。

rem // Store current date and time once in the same line:
set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%"
rem // Resolve AM/PM time:
set "HOUR=%CURRTIME:~,2%"
if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2%

ただし、%DATE%および%TIME%の戻り値は、真夜中に実行されたときに異なる日を反映する可能性があります。

%CURRDATE%%CURRTIME%で同じ日にする唯一の方法は次のとおりです。

rem // Store current date and time once in the same line:
set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%"
rem // Resolve AM/PM time:
set "HOUR=%CURRTIME:~,2%"
if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Fix date/time midnight discrepancy:
if not "%CURRDATE%" == "%DATE%" if %CURRTIME:~0,2% equ 0 set "CURRDATE=%DATE%"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2%

もちろん、説明されている問題の発生は非常にありそうにありませんが、ある時点で発生し、説明できない奇妙な障害を引き起こします。


説明されている問題は、 answer by user Stephan および answer で説明されているwmicコマンドに基づくアプローチでは発生しません。ユーザーによる PA。 なので、そのうちの1つに行くことを強くお勧めします。 wmicの唯一の欠点は、処理速度がはるかに遅いことです。

0
aschipfl

ファイル名にはスペースを使用できます。パスとファイル名を引用符で囲むと、そのまま飛ぶことがあります。バッチファイルで使用しているものは次のとおりです。

svnadmin hotcopy "C:\SourcePath\Folder" "f:\DestPath\Folder%filename%"

%filename%にスペースが含まれていてもかまいません。

0
Marty