「cd /d」が先行すると、For ループが機能しない (Windows 10、バッチ ファイル)

「cd /d」が先行すると、For ループが機能しない (Windows 10、バッチ ファイル)

これを MP4 ファイルのフォルダー内のバッチ ファイルで実行すると、最後に変更された MP4 ファイルが変数として設定され、デフォルトのメディア プレーヤーで再生できるようになります。

:: Set last modified MP4 file in current folder, as a variable...
for /f "eol=: delims=" %%F in ('dir /B /O:D *.mp4') do @set "newest=%%F"

:: Play the file (opens in default media player)...
"%newest%"

MP4 ファイルのフォルダー外のバッチ ファイルに次のコードを配置しようとすると、cd /dfor ループによって無視され、機能しません。

:: Change to directory containing MP4 files...
cd /d "C:\My Videos"

:: Set last modified MP4 file in "C:\My Videos", as a variable (not working)...
for /f "eol=: delims=" %%F in ('dir /B /O:D *.mp4') do @set "newest=%%F"

:: Copy the MP4 to current folder...
xcopy "%newest%" "%CD%" /i /r /v /k /f /c /h /y >nul 2>&1

:: Change back to current directory
cd /d "%CD%"

ご覧のとおり、 for ループ コマンドは各例でまったく同じです。最初の例では機能しますが、2 番目の例では機能しません。

各コマンドの間に を入れてpauseエラーが表示されるかどうかを確認してみましたが、エラーは表示されませんでした。

周りの二重引用符を削除してみましたが%CD%、違いはありませんでした。

Setlocal EnableDelayedExpansionコマンドの前に入れようとしましたが、何も起こりません。

以前、DIR コマンドを追加して FOR ループで直接フォルダーを指定しようとしました/Sが、何らかの理由で間違った MP4 ファイルがコピーされ、変更日が意味のないランダムな日付になり、最後に変更された MP4 ではなくなりました。そのコマンドは次のようになります。

for /f "eol=: delims=" %%F in ('dir /B /S /O:D "C:\My Videos\*.mp4"') do @set "newest=%%F"

確かに MP4 が変数として設定されますが、正しいものではありません。

MP4 ファイルのフォルダー内でバッチ ファイルを使用すると、常にそのように機能することがわかっています。

なぜこれが機能しないのかを解明できる人がいれば、事前に感謝します。

答え1

スクリプト%CD%では、最初から最後まで元の値を維持すると想定しています。しかし、この変数はそうは機能しません。インタープリタによって動的に更新され、常に現在のディレクトリを表します。そして、最初のcdコマンドの後、パスはC:\My Videos なる「現在の」ディレクトリ。

つまり、dir新しい場所でファイルを探し、xcopy見つかったファイルを元の場所にコピーし直そうとしますが、最後にはcd /d "%CD%"「現在いるディレクトリに変更してください」と表示されます。この時点では %CD% なので、以前の場所に戻ることはできません。「C:\マイビデオ」。

以前のパスを明示的に記録する必要があります前に他の場所に cd する (例: . を使用) set "PrevDir=%CD%"

関連情報