バッチジョブでファイル名をタイムスタンプとして作成する


90

毎日実行するバッチジョブがあり、ファイルをピックアップフォルダーにコピーします。そのファイルのコピーを取り、それをファイル名の付いたアーカイブフォルダーにドロップしたい

 yyyy-MM-dd.log

Windowsバッチジョブでこれを行う最も簡単な方法は何ですか?

基本的には、このUnixコマンドに相当するものを探しています。

cp source.log `date +%F`.log

Windowsで必要な形式の日付文字列を取得する場合、.batファイルは、提案されたソリューションと同じくらい悪いように見えます。正直なところ、マシンで使用可能なプログラミング言語(java、ruby、perlなど)を確認し、5秒の実行可能ファイルを作成して必要なものを提供します。適切な形式で日付を取得するために複数行のコードを必要とする.batファイルを維持することに時間を費やすことはありません。
99Sono 2016年

回答:


105
CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log

ただし、ロケールに依存します。%DATE%がローカライズされているかどうか、またはWindowsで短い日付に指定された形式に依存しているかどうかはわかりません。

これは、この回答から現在の日付を抽出するためのロケールに依存しない方法ですが、WMICおよびに依存しFOR /Fます:

FOR /F %%A IN ('WMIC OS GET LocalDateTime ^| FINDSTR \.') DO @SET B=%%A
CP source.log %B:~0,4%-%B:~4,2%-%B:~6,2%.log

6
インデックスを少しいじる必要がありましたが、これでうまくいったようです。(マイナスインデックスロジックを完全に理解しているわけではありませんが)%DATE:〜-4%-%DATE:〜-7、-5%-%DATE:〜-10、-8%.log
Eoin Campbell

1
すべての正のインデックスを使用する場合は、%DATE:〜10,4%-%DATE:〜4,2%-%DATE:
〜7,2

(私はこれを自分が取り組んだ他の何かから取っただけで、それはずっと前のことで、なぜ私が元々行った方法でそれをしたのか、私には
わかりません

3
これは他のロケールでは機能しません。私の場合、コマンドは戻ります2014-5.-01(それがの場合2014-05-26)。これを含むスクリプトを公開する場合は、十分に注意してください。
amenthes 2014年

5
時間にこれを使用します(ミリ秒を削除します): %time:~-11,2%-%time:~-8,2%-%time:~-5,2%
MRC

48

これは私にとってはうまくいき、ファイル名セーフなソリューションでした(MM-dd-YYYY形式が生成されます)。

C:\ set SAVESTAMP=%DATE:/=-%@%TIME::=-%
C:\ set SAVESTAMP=%SAVESTAMP: =%
C:\ set SAVESTAMP=%SAVESTAMP:,=.%.jpg
C:\ echo %SAVESTAMP%
11-04-2012@20-52-42.79.jpg

最初のコマンドは、DATEと置き換えを取る/-TIMEと置き換えを取る、:-、とTIME形式@ DATEにそれらを兼ね備えています。2番目のsetステートメントはスペースを削除し、3 番目のステートメントは拡張子にset置き換え,.追加し.jpgます。

上記のコードは、さらに処理するためにセキュリティIPカメラから画像を取得する小さなスクリプトで使用されています。

:while
set SAVESTAMP=%DATE:/=-%@%TIME::=-%
set SAVESTAMP=%SAVESTAMP: =%
set SAVESTAMP=%SAVESTAMP:,=.%.jpg
wget-1.10.2.exe --tries=0 -O %SAVESTAMP% http://admin:<password>@<ip address>:<port>/snapshot.cgi
timeout 1
GOTO while

コンソールの出力には10-12-2014@14-22-59,44.jpg、ミリ秒の前にカンマが付いています
BeNdErR

1
ステートメントのset SAVESTAMP=%SAVESTAMP:,=.%.jpg前に追加してechoください。それがうまくいけば、答えを更新します。
Daniel Sokolowski、2014

1
これはロケールに依存しません。08.06.2016@15-42-20,33.jpg私のドイツのラップトップとWed06-08-2016@15-43-45.89.jpg私の英語のラップトップに戻ります。
飯能坊2016年

5
しかし、それでもロケールに依存せず、正しい(iso8601)形式を作成しませんyyyy-MM-dd
jeb

1
最初の行がまだロケールに依存しないと主張しているのは
不愉快

16

以下のためのフランス語ロケール(フランス)ONLY、気をつけているため/、日付に表示されます:

echo %DATE%
08/09/2013

ログファイルの問題については、フランス語ロケールのみの提案を以下に示します。

SETLOCAL
set LOGFILE_DATE=%DATE:~6,4%.%DATE:~3,2%.%DATE:~0,2%
set LOGFILE_TIME=%TIME:~0,2%.%TIME:~3,2%
set LOGFILE=log-%LOGFILE_DATE%-%LOGFILE_TIME%.txt
rem log-2014.05.19-22.18.txt
command > %LOGFILE%

優れた!少し読みにくいですが、好きなように出力をフォーマットできます。
davitof 2014年

2
素晴らしいですが、白い文字を避けたい場合は注意してください"_0:00"
。HOUR

1
この回答に対して「log- / 18 /。0.Sa- 9.16.txt」が表示されます。
ledlogic

@ledlogic:あなたのロケールは何ですか?この回答はフランス語ロケール用です。
オービン2017

1
動作しませんWindows 7でこれを取得します-log- / 05 /。0.We-18.13.tx
Sam B

10

次に、ロケールに依存しないソリューションを示します(SetDateTimeComponents.cmdという名前のファイルにコピーします)。

@echo off
REM This script taken from the following URL:
REM http://www.winnetmag.com/windowsscripting/article/articleid/9177/windowsscripting_9177.html

REM Create the date and time elements.
for /f "tokens=1-7 delims=:/-, " %%i in ('echo exit^|cmd /q /k"prompt $d $t"') do (
   for /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do (
      set dow=%%i
      set %%a=%%j
      set %%b=%%k
      set %%c=%%l
      set hh=%%m
      set min=%%n
      set ss=%%o
   )
)

REM Let's see the result.
echo %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss%

すべての.cmdスクリプトを同じフォルダー(%SCRIPTROOT%)に入れました。日付/時刻値を必要とするスクリプトは、次の例のようにSetDateTimeComponents.cmdを呼び出します。

setlocal

@echo Initializing...
set SCRIPTROOT=%~dp0
set ERRLOG=C:\Oopsies.err

:: Log start time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
@echo === %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss% : Start === >> %ERRLOG%

:: Perform some long running action and log errors to ERRLOG.

:: Log end time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
@echo === %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss% : End === >> %ERRLOG%

例が示すように、日付/時刻値を更新する必要があるときはいつでもSetDateTimeComponents.cmdを呼び出すことができます。独自のSetDateTimeComponents.cmdファイルで時間解析スクリプトを非表示にすることは、醜い詳細を隠し、さらに重要なことにタイプミスを回避するための優れた方法です。


2
申し訳ありませんが、これはロケールに依存しません。フランス語のWindowsでは、「18 -2014- @ 13:14:43」になります
davitof

1
確認可能:ロケールに依存しません。prompt $d $t私のシステムでは30.05.2016 15:35:56,93を返します。
飯能房

7

引き裂い%DATE%%TIME%バラバラにして一緒につぶすという考えは、せいぜい壊れやすいように見えるので、Powershellワンライナーを使用する別の方法を次に示します。

for /f %i in ('powershell -c "get-date -format yyyy-MM-dd--HH-mm-ss"') do @set DATETIME=%i
set LOGFILE=my-script-%DATETIME%.txt

のリファレンスget-datehereで、.NETスタイルとUNIXスタイルの両方のフォーマットオプションがあります。


6

私はこれを頻繁に使用し、すべてを1つのコピーコマンドに入れます。次の例はexample.txtをexample_YYYYMMDD_HHMMSS.txtとしてコピーします。もちろん、好みの形式に合わせて変更できます。引用符は、ファイル指定にスペースがある場合にのみ必要です。まったく同じ日付/タイムスタンプを再利用したい場合は、それを変数に格納する必要があります。

copy "{path}\example.txt" "{path}\_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"

6

これにより、出力が2桁の値になることが保証されます。診断セクションのコメントを外すことにより、出力を好みに応じて再配置してテストできます。楽しい!

(私は他のフォーラムからこれをたくさん借りました...)

:: ------------------ Date and Time Modifier ------------------------

@echo off
setlocal

:: THIS CODE WILL DISPLAY A 2-DIGIT TIMESTAMP FOR USE IN APPENDING FILENAMES

:: CREATE VARIABLE %TIMESTAMP%

for /f "tokens=1-8 delims=.:/-, " %%i in ('echo exit^|cmd /q /k"prompt $D $T"') do (
   for /f "tokens=2-4 skip=1 delims=/-,()" %%a in ('echo.^|date') do (
set dow=%%i
set %%a=%%j
set %%b=%%k
set %%c=%%l
set hh=%%m
set min=%%n
set sec=%%o
set hsec=%%p
)
)

:: ensure that hour is always 2 digits

if %hh%==0 set hh=00
if %hh%==1 set hh=01
if %hh%==2 set hh=02
if %hh%==3 set hh=03
if %hh%==4 set hh=04
if %hh%==5 set hh=05
if %hh%==6 set hh=06
if %hh%==7 set hh=07
if %hh%==8 set hh=08
if %hh%==9 set hh=09


:: --------- TIME STAMP DIAGNOSTICS -------------------------

:: Un-comment these lines to test output

:: echo dayOfWeek = %dow%
:: echo year = %yy%
:: echo month = %mm%
:: echo day = %dd%
:: echo hour = %hh%
:: echo minute = %min%
:: echo second = %sec%
:: echo hundredthsSecond = %hsec%
:: echo.
:: echo Hello! 
:: echo Today is %dow%, %mm%/%dd%. 
:: echo.
:: echo. 
:: echo.
:: echo.
:: pause

:: --------- END TIME STAMP DIAGNOSTICS ----------------------

:: assign timeStamp:
:: Add the date and time parameters as necessary - " yy-mm-dd-dow-min-sec-hsec "

endlocal & set timeStamp=%yy%%mm%%dd%_%hh%-%min%-%sec%
echo %timeStamp%

2

現在の日付をファイル名として含むファイルを作成します(例:2008-11-08.dat)

echo hello > %date%.dat    

現在の日付あり、ただし「-」なし(例:20081108.dat)

echo hello > %date:-=%.dat   

2

多分これは助けることができます:

echo off
@prompt set date=$d$_ set time=$t$h$h$h
echo some log >> %date% %time%.log
exit

または

echo off
set v=%date%.log
echo some log >> %v%

いいねSecko ...その%date%値には、私が探しているものがあるようです。SETステートメントについて説明できる可能性があります。$ d $ _setと$ t $ h $ h $ hとは正確には何ですか
Eoin Campbell

1
setは「SET変数」ステートメントです。ここで、日付変数は$ d $ _(日+残り)、時間変数は$ t $ h $ h $ h(時間+ミリ秒)です。プロンプトラインがなくても正常に機能する一連の変数を使用して、それをどのように実行できるかを示しました。基本的にこれを設定しようとしましたdate =%YYYY %% MM %% DD%がここでLinuxを実行していて、SciTEでスクリプトをコンパイルしているため、機能するかどうかわかりません。それが機能しない場合は申し訳ありません。
Secko

追加するのを忘れて、$ _は改行です。
Secko、2009年

1
@prompt // $ d $ _ $ t $ h $ h $ h $ h $ h $ h //
Secko

これもロケールに依存しないことに注意してください。日付は現在のカルチャ設定にフォーマットされています。私の場合はDD.MM.YYYY(ドイツ語の場合)です。
飯能房

2

私は現在のタイムスタンプを出力するために小さなCプログラムを作成しました(ロケールセーフ、不良文字なし...)。次に、FORコマンドを使用して、結果を環境変数に保存します。

:: Get the timestamp
for /f %%x in ('@timestamp') do set TIMESTAMP=%%x

:: Use it to generate a filename
for /r %%x in (.\processed\*) do move "%%~x" ".\archived\%%~nx-%TIMESTAMP%%%~xx"

ここにリンクがあります:

https://github.com/HarryPehkonen/dos-timestamp


2

私はこのスレッドが古いことを知っていますが、これをここに追加したいと思います。これの良い点は、常に実行されているバッチファイルのループに配置できることです。サーバー稼働時間ログまたは何か。とにかくそれを使っています。これが誰かの役に立つことを願っています。

@setlocal enableextensions enabledelayedexpansion
@echo off

call :timestamp freshtime freshdate
echo %freshdate% - %freshtime% - Some data >> "%freshdate - Somelog.log"

:timestamp
set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
set FreshTime=%hour%:%min%:%secs%

set year=%date:~-4%
set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
set day=%date:~7,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
set FreshDate=%month%.%day%.%year%

これは私にとっては便利でしたが、「。cmd」ファイルでは、「robocopy」コマンドラインのファイル名に「FreshTime」変数のコロンを使用するとエラーが発生しました。 ERROR : Invalid Parameter #12 : "/LOG:C:\opt\Sync_08.10.2020_16:27:39.log"代わりにダッシュを使用しました:set FreshTime=%hour%-%min%-%secs%
netdesignate

2

現在のローカル形式を簡単に検出して、形式で日付を取得できます。次に例を示します。

::for 30.10.2016 dd.MM.yyyy
if %date:~2,1%==. set d=%date:~-4%%date:~3,2%%date:~,2%
::for 10/30/2016 MM/dd/yyyy
if %date:~2,1%==/ set d=%date:~-4%%date:~,2%%date:~3,2%
::for 2016-10-30 yyyy-MM-dd
if %date:~4,1%==- set d=%date:~,4%%date:~5,2%%date:~-2%
::variable %d% have now value: 2016103 (yyyyMMdd)
set t=%time::=%
set t=%t:,=%
::variable %t% have now time without delimiters
cp source.log %d%_%t%.log

2

私はこれが古い投稿であることを知っていますが、FARより簡単な答えがあります(多分それは新しいバージョンのWindowsでのみ機能します)。次のように、DATEおよびTIME dosコマンドに/ tパラメータを使用して、日付または時刻のみを表示し、設定を求めるプロンプトを表示しないようにします。

@echo off
echo Starting test batch file > testlog.txt
date /t >> testlog.txt
time /t >> testlog.txt

1

1)GNU coreutilsをダウンロードできます GNU dateに付属するを

2)VBScriptを使用できます。これにより、Windowsでの日付操作が容易になります。

Set objFS = CreateObject("Scripting.FileSystemObject")
strFolder = "c:\test"
Set objFolder = objFS.GetFolder(strFolder)
current = Now
mth = Month(current)
d = Day(current)
yr = Year(current)
If Len(mth) <2 Then
    mth="0"&mth
End If
If Len(d) < 2 Then
    d = "0"&d
End If
timestamp=yr & "-" & mth &"-"& d
For Each strFile In objFolder.Files
    strFileName = strFile.Name
    If InStr(strFileName,"file_name_here") > 0 Then
        BaseName = objFS.GetBaseName(strFileName)
        Extension = objFS.GetExtensionName(strFileName)
        NewName = BaseName & "-" & timestamp & "." & Extension
        strFile.Name = NewName
    End If
Next

次のようにスクリプトを実行します。

c:\test> cscript /nologo myscript.vbs

0

これは(私の)ドイツ語ロケールでうまく機能します。ニーズに合わせて調整できるはずです...

forfiles /p *PATH* /m *filepattern* /c "cmd /c ren @file 
%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_@file"

%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%ポルトガルの場所でも動作します!YYYYMMDD
フェルナンドファブレティ

0

展開用の大きなzipファイルの場合、15分を使用します。このページの他の誰もそれについて以前に言及していなかったので、ここに小さなスクリプトを入れます。

set /a "quarter_hours=%time:~0,2%*4 + %time:~3,2% / 15"
set "zip_file=release_%DATE:~-4%.%DATE:~4,2%.%DATE:~7,2%.%quarter_hours%.zip"

それはまだ真夜中から午前5時までの15分のゼロパッドをゼロにしませんが、衝突をほとんど起こさずに1日に複数回スタンプリリースを行うことができるようにします。

お役に立てば幸いです。


0

マーティンの提案を少し調整して、ファイル名にタイムスタンプを追加しました:

forfiles /p [foldername] /m rsync2.log /c "cmd /c ren @file %DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_%time:~-11,2%-%time:~-8,2%-%time:~-5,2%-@file

10:17:21の場合23/10/2019結果は次のとおりです。

20191023_10-17-21-rsync2.log

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.