2

Windows バッチ ファイルは、FOR ループで不可解にファイル名を変更します

MP3 ファイル名のライブラリの名前を変更するための小さな Windows 7 バッチ ファイルがあります。この質問には、最後の数行のコードのみを含めました。変数からディレクトリ内の各ファイル名にテキスト文字列 (アーティスト名) を追加するコードのセクションに関する 1 つの問題を除いて、問題なく動作します。(解決したら、私のバッチ ファイルは "set /p var=" を使用して、変数に入力するテキストを要求します。)

このテストで使用される 2 つのサンプル ファイル名は次のとおりです。

01-serious song.mp3
02-happy song.mp3

コードのこのセクションでは、問題が発生します。

@echo off
setlocal enabledelayedexpansion
::Temporay test variable
set str=Artist-
for %%a in (*.mp3) do (
  set oldName=%%a
  set newName=!str!!oldName!
  ren "!oldName!" "!newName!"
)
endlocal

その結果、02 ファイルには文字列が 1 回追加された (意図したとおり) という結果になりますが、01 ファイル名には文字列が 2 回追加されます (エラー)。

Artist-Artist-01-serious song.mp3
Artist-02-happy song.mp3

私はインターネットをくまなく調べましたが、これについての議論は 1 つも見つかりませんでした。そして、自分で約 8 時間かけて作業したとは言いたくありません。多くのテストと調査の結果、rename ステートメントが何らかの形でこれを引き起こしていると考えています。

そこで、rename コマンドを含むサブルーチンを呼び出すようにバッチ ファイルを変更し、for ステートメントに干渉していると考えました。それにはまだ問題がありました。次に、以下に示すようにエコー コマンドを使用してバッチ ファイルを編集し、テストしました。

バージョン 2 テスト:

@echo off
setlocal enabledelayedexpansion
set str=Artist-
for %%a in (*.mp3) do (
set oldName=%%a
set newName=!str!!oldName!
  call :Action
echo.
echo back in For loop
)
echo.
echo For loop completed
echo !oldName!
echo !newName!
endlocal
goto:eof

:Action
echo.
echo start of Action loop
echo !oldName!
echo !newName!
ren "!oldName!" "!newName!"
echo end of Action loop

CMD 画面に表示される結果の出力は次のとおりです。

start of Action loop
01-serious song.mp3
Artist-01-serious song.mp3
end of Action loop

back in For loop

start of Action loop
02-happy song.mp3
Artist-02-happy song.mp3
end of Action loop

back in For loop

start of Action loop
Artist-01-serious song.mp3
Artist-Artist-01-serious song.mp3
end of Action loop

back in For loop

For loop completed
Artist-01-serious song.mp3
Artist-Artist-01-serious song.mp3

これは、サブルーチンが適切に呼び出されて 2 回返されることを示していたため、興味深いものでした。その後、どういうわけか 3 回目に呼び出され、01 ファイルの名前が再度変更され、変数が 2 回目に追加されたようです。

ren ステートメントの前に echo を配置すると、サブルーチンが 2 回しか呼び出されないことが画面出力に示されますが、もちろん、ファイルの名前は変更されません。名前の変更の代わりに移動コマンドも使用してみましたが、同じ問題の結果が得られました。

ですから、私の質問は、for ループがサブルーチンを 3 回呼び出して 01 ファイルを 2 回処理するのはなぜですか? また、意図したとおりに動作させるにはどうすればよいですか?

ありがとう、ピート。

4

2 に答える 2

5

試す

for /f "delims=" %%a in (' dir /b /a-d *.mp3') do (

問題は、元の構文が次のファイル名を見つけることです。これは、新しいファイル名 (プレフィックス付き) が論理的に古いものよりも「大きい」ため、名前が変更されたファイルを見つけます。

を使用dirすると、ファイル名のリストが作成され、完全に作成されたリストが処理されます。したがって、ファイルの名前が変更されてもリストは変化しません。

この"delims="句は、ファイル名のデフォルトの解析が無効であることを保証します。それ以外の場合、ファイル名は一連の [スペースで区切られた] トークンとして解釈されます。

于 2013-06-20T04:28:12.253 に答える
2

これを置き換えます:

for %%a in (*.mp3) do (
  set oldName=%%a
  set newName=!str!!oldName!
  レン「!oldName!」"!新しい名前!"
)

それと:

for /f "delims=" %%a in ('dir /b /ad *.mp3') do (
  set "oldName=%%~a"
  set "newName=%str%!oldName!"
  レン「!oldName!」"!新しい名前!"
)

必要に応じて、これについては後で説明できますが、Peter の方が速かったです :)

于 2013-06-20T04:28:52.870 に答える