Win-1064ビットを使用しています。
私のWindowsマシンで次のディレクトリ構造を考えると...
c:\tmp\Logs_UAT\
'-> folder1
| '-> test.txt
'-> folder2
'-> test.txt
...各ディレクトリ内のすべてのファイルの名前をディレクトリ名の前に付けて名前を変更しようとしています。
c:\tmp\Logs_UAT\
'-> folder1
| '-> folder1_test.txt
'-> folder2
'-> folder2_test.txt
これを実現するために、FORを使用して%basedir%
内のファイルを再帰的にループし、各ディレクトリで、内部のFOR「ループ」を使用して現在のディレクトリ名を取得し、名前を変更します。ただし、現在のディレクトリは通常正しく派生していません。問題を再現できる.batファイルは次のとおりです。
@echo off
set basedir=c:\tmp\Logs_UAT
for /R %basedir% %%I in (*) DO (
cd %%~pI
for %%G in (.) do echo %%~nxG> temp.temp
set /P curdir=<temp.temp
del /f temp.temp
echo.
echo -------------------
echo %%I
dir
echo %curdir%
echo -------------------
)
両方のファイルの%curdir%
に同じ値を出力します。
C:\tmp>test.bat
-------------------
c:\tmp\Logs_UAT\folder1\test.txt
Datenträger in Laufwerk C: ist OSDisk
Volumeseriennummer: D280-2DC0
Verzeichnis von C:\tmp\Logs_UAT\folder1
06.05.2020 19:29 <DIR> .
06.05.2020 19:29 <DIR> ..
06.05.2020 19:02 0 test.txt
1 Datei(en), 0 Bytes
2 Verzeichnis(se), 291.684.151.296 Bytes frei
folder2
-------------------
.
-------------------
c:\tmp\Logs_UAT\folder2\test.txt
Datenträger in Laufwerk C: ist OSDisk
Volumeseriennummer: D280-2DC0
Verzeichnis von C:\tmp\Logs_UAT\folder2
06.05.2020 19:29 <DIR> .
06.05.2020 19:29 <DIR> ..
06.05.2020 19:02 0 test.txt
1 Datei(en), 0 Bytes
2 Verzeichnis(se), 291.684.151.296 Bytes frei
folder2
-------------------
C:\tmp\Logs_UAT\folder2>
私は試した:
追加のソフトウェアを持っていない可能性のある他のユーザーにスクリプトを配布する必要があるため、標準のWindowsユーティリティを使用することをお勧めします。
FORループ内のWindowsコマンドプロンプトで現在のディレクトリ名を取得するにはどうすればよいですか?
確かにDelayedExpansionが役に立ちました、DavidPostillに感謝します。作業スクリプトは次のとおりです。
@echo off
SETLOCAL EnableDelayedExpansion
set basedir=c:\tmp\Logs_UAT
for /R %basedir% %%I in (*) DO (
cd %%~pI
for %%G in (.) do echo %%~nxG> temp.temp
set /P curdir=<temp.temp
del /f temp.temp
echo !curdir!
)
endlocal
@echo off
set "_=echo\ -------------------"
for /D /R "c:\tmp\Logs_UAT" %%I in (*
)do %_% & echo\%%~nxI & dir "%%~nxI" & echo\ %%~nxI & %_%
-------------------
Volume in drive C has no label.
Volume Serial Number is 32E8-70C5
Directory of c:\tmp\Logs_UAT\folder1
05/06/2020 02:40 PM <DIR> .
05/06/2020 02:40 PM <DIR> ..
05/06/2020 02:41 PM 8 test.txt
1 File(s) 8 bytes
2 Dir(s) 3,128,999,936 bytes free
folder1
-------------------
-------------------
Volume in drive C has no label.
Volume Serial Number is 32E8-70C5
Directory of c:\tmp\Logs_UAT\folder2
05/06/2020 02:47 PM <DIR> .
05/06/2020 02:47 PM <DIR> ..
05/06/2020 02:48 PM 7 folder2.txt
1 File(s) 7 bytes
2 Dir(s) 3,128,999,936 bytes free
folder2
-------------------
複数のfor
ループを使用する必要はなく、すべてのサブディレクトリで再帰的に1つのループでfor /D /R
を使用します。これにより、DelayedExpansion
は不要になります。
FOR /R - Loop through files (recursively)
FOR /D - Loop through several folders/directories
Rem :: Set your folder /Directory/Recursively tree starting at "c:\tmp\Logs_UAT"
For /D /R "c:\tmp\Logs_UAT"
temp.temp
と追加のfor
ループを使用して、ディレクトリ全体でファイルfor /D
を作成および削除する必要があるのはなぜですか?ループ内の現在のフォルダーの名前(すべてのsub/R
irectoriesで/D
ecursive)が変数%%~nxI
(および他の多くの拡張可能なものも)に格納されている場合は、ループで使用するために、それらを使用してください...
Use the FOR variable syntax replacement:
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
The modifiers can be combined to get compound results:
%~pnI - expands %I to a path and file name only
%~pnxI - expands %I to a path, file name and extension only
)do %_% & echo\%%~nxI & dir "%%~nxI" & echo\ %%~nxI & %_%
Obs.: directory
nameでの%%~x
の使用についてss64.com
の観察ノート:
Full Stop Bug
Although Win32 will not recognise any file or directory name that begins or ends
with a '.' (period/full stop) it is possible to include a Full Stop in the middle
of a directory name and this can cause issues with FOR /D.
Parameter expansion will treat a Full Stop as a file extension, so for a directory
name like "Sample 2.6.4" the output of %%~nI will be truncated to "Sample 2.6" to
return the whole folder name use %%I or %%~nxI
DelayedExpansion
を使用する必要はなく、cmd /v/c echo\!curdir!
またはecho\%%~nxI
を使用できます。
それはまさにあなたのコードがあなたの質問(そして答え)でしていることです、あなたは複数のfor
ループを使用しています、そこであなたが単一を使用したならDelayedExpansion
は必要ありません for /D /R
使用する場合 %%~nxI
同じ結果を選択した行で使用する場合、1つ以上のfor
ループを使用している場合は、実行時にcmd /v /c echo\!curdir!
を使用してその時点で変数値を展開し、DelayedExpansion
を有効にすることもできます。
)do set "curdir=%%~nxI" && cmd /v /c " echo\!curdir!"
コード出力の質問と同じように出力を取得するには、バナーの変数(set _=echo\ ----
)を設定/使用し、これを目的のレイアウト出力に調整します。
)do %_% & echo\%%~nxI & dir "%%~nxI" & echo\ %%~nxI & %_%
または、1つの従来のフォーマットで
@echo off
set "_=echo\ -------------------"
for /D /R "c:\tmp\Logs_UAT" %%I in (*)do (
%_%
echo\%%~nxI
dir "%%~nxI"
echo\ %%~nxI
%_%
)
for /D /R
ループを含む1行の1つの単純で短い出力オプションについては、次のことを試すことができます。
@echo off
for /d /r "c:\tmp\Logs_UAT" %%I in (*)do set "curdir=%%~nxI" && cmd /v /c " echo\!curdir!"