あなたは、バグを追跡するのが難しい複雑な問題を抱えています。
コードがどのように失敗しているかを説明する前に、FORFILESではなくFORを使用すると、はるかに簡単で迅速なソリューションを提供します。
また、%DATE%
と%TIME%
を操作する代わりに、WMICを使用してタイムスタンプを信頼できる方法で取得しますが、これはコンピュータの構成によっては失敗する可能性があります。私のコードはタイムスタンプをYYMMDDhhmm
として生成しています。これは私があなたが努力していると信じているものです。
@echo off
setlocal
set "ts="
for /f "skip=1" %%A in ('wmic os get localDateTime') do if not defined ts set "ts=%%A"
for %%F in ("C:\Batches\ftp_outputfiles\*.txt") do ren %%F "%%~nF-%ts:~0,12%.txt"
[OK] - 元のコードの多くの問題とその影響を表示するようになりました。
1)独自のTIME変数を決して定義しないでください。それによって、後続のコードが動的TIME値にアクセスできなくなります。
2)SETLOCALを一番上に忘れたため、スクリプトが終了した後もTIMEの定義が維持されます。つまり、後続の実行でも動的なTIME値は取得されませんが、以前の実行からの結果の部分文字列が使用されます。
3)実際にはバグではありませんが、変数値には引用符は必要ありません。 set var="someValue"
の代わりにset "var=someValue"
を使用することをお勧めします。前者は構文解析の観点から式を引用していますが、引用符は代入に含まれていません。後者の形式には値の引用符が含まれます。
4)予期しないエラーメッセージにつながる最終的なバグ - FORFILESコマンドは\"
をエスケープした引用符として扱いますので、\ P値はあなたの考えるよりもはるかに長くなります! FORFILES引数パーサは1つの引数として引用符の間のすべてを保持する
"C:\Batches\ftp_outputfiles\" /M *.txt /C "cmd
、しかし:
あなたのコードは、(省略)
Forfiles /P "C:\Batches\ftp_outputfiles\" /M *.txt /C "cmd /c ren @file @fname-...txt"
/Pオプションのように解析された値を期待しています\"
はエスケープされているので、次の引用符まで続く。次の"
の後にトークン区切り文字がないので、cmd
も値に含まれます。
次のトークンは、値を期待する有効なオプションである/c
です。したがって、ren
がコマンド値として扱われます。
次のトークンは有効なオプションではない@FILE
です。したがって、ERROR: Invalid argument/option - '@file'.
エラーメッセージ。必要に応じて、引数は引用符で終わるよう
この厄介な解析問題を回避するための簡単な方法は、パスから末尾の\
をドロップすることです:
forfiles /P "C:\Batches\ftp_outputfiles" /M ....
別のオプションは、引用符をドロップすることです
が、それだけでパスに引用符を必要とするスペースのような文字がないために機能します。
forfiles /P C:\Batches\ftp_outputfiles\ /M ....
パスから末尾のバックスラッシュを削除します。 – LotPings
'@ file'が' 'filename.ext" 'として出力すると、' @ fname-'はファイル名' -'として出力し、ファイル名には二重引用符を使用できません。 – Compo
@Compo - 引用符の問題など、複数の問題があります。しかし、あなたの考え方ではありません。 REN(および他のコマンド)では、パス内で引用符を使用することができ、それらは削除されます。したがって 'ren file.txt" this "と" that.txt "'は 'thisとthat.txt'という名前のファイルになります。しかし、トークン区切り文字や毒物文字に関しては、どの文字が引用されるか心配する必要があります。 – dbenham