こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

バッチファイル パス名に( )や!がある場合の対処

2つのフォルダの配下にあるすべてのファイルが一致していることを確認する
下記のtest.batのプログラムでは、フォルダ名やファイル名の中に、
()や!が含まれていない時は正しく動作しますが、
含まれていると正しく動作しません。

(問1)
パスに( )が含まれている場合
(例)set x=C:\tmp\sample\DATA(1)_SP\
  set y=C:\tmp\sample\DATA(2)_SP\
は、
echo !j:%x%=!>> list1.txt の所で
「_SP\ の使い方が誤っています。」
と表示されて正しく動作しませんが
どのようにすればよいでしょうか。

(問2)
echo !j:%x%=!>> list1.txt

echo !j:!x!=!>> list1.txt
にすると、環境変数xの部分が空白に置き換わらないのですが
なぜでしょうか。

(問3)
パスに!が含まれている場合
(例)DATA1とDATA2の配下に!ABCというフォルダがある場合
  C:\tmp\sample\DATA1\!ABC\…
は、
for /F "delims=" %%i in (list01.txt)
の取り出しの時に!が抜け落ちてしまい
以後の処理が正しく行えません。
!が抜け落ちないようにするには
どのようにすればよいでしょうか。

よろしくお願いします。

---test.bat----------------------------------------------
setlocal enabledelayedexpansion
@echo off

set x=C:\tmp\sample\DATA1\
set y=C:\tmp\sample\DATA2\

if exist list1.txt del list1.txt
if exist list2.txt del list2.txt

dir /b /s /a-d %x% > list01.txt
dir /b /s /a-d %y% > list02.txt

for /F "delims=" %%i in (list01.txt) do (
set j=%%i
echo !j:%x%=!>> list1.txt
)

for /F "delims=" %%i in (list02.txt) do (
set j=%%i
echo !j:%y%=!>> list2.txt
)

fc /n /w list1.txt list2.txt > result.txt

if ERRORLEVEL 1 (
set /p z="両者は一致しませんでした。"
goto :EOF
) else (
if exist result.txt del result.txt
)

set cnt=1
set err_cnt=0
for /F "delims=" %%i in (list1.txt) do (
set /p<NUL=[!cnt!]
fc /n /w "%x%%%i" "%y%%%i" >> nul
if ERRORLEVEL 1 (
echo [!cnt!] %x%%%i >> result.txt
fc /n /w "%x%%%i" "%y%%%i" 2>&1 >> result.txt
set /a err_cnt=!err_cnt!+1
)
set /a cnt=!cnt!+1
)

echo;

if %err_cnt%==0 (
set /p z="両者は完全に一致しました。"
) else (
set /p z="%err_cnt% 個が一致しませんでした。"
)
-------------------------------------------------
【動作環境】Windows7 コマンドプロンプト(Ver.6.1.7601)
 

投稿日時 - 2018-10-13 09:34:52

QNo.9547120

困ってます

質問者が選んだベストアンサー

>echo !j:"%x%"=!>> list1.txt
>としてみたのですがうまくいきませんでした。

変数jの中のパスは"で囲まれていないので、"%x%"はマッチせず、置換されません。
echo "!j:%x%=!">> list1.txt
であれば、置換が発生するでしょう。

>例えば、jがABCDEでxがBCDの時は、%j:%x%=%はAEになると思いますが

なりませんよ。

>!ABCとDEFというフォルダがあってこの中にファイルがある場合、

回答に書いたのは、サブディレクトリを考慮していません。

これでどうでしょうか。
@echo off
set x=D:\temp\sample\DATA(1)_SP\
set y=D:\temp\sample\DATA(2)_SP\

if exist list1.txt del list1.txt
if exist list2.txt del list2.txt

dir /b /s /a-d "%x%" > list01.txt
dir /b /s /a-d "%y%" > list02.txt

for /F "delims=" %%i in (list01.txt) do call :SUB "%%i" "%x%" list1.txt

for /F "delims=" %%i in (list02.txt) do call :SUB "%%i" "%y%" list2.txt

fc /n /w list1.txt list2.txt > result.txt

if ERRORLEVEL 1 (
set /p z="両者は一致しませんでした。"
goto :EOF
) else (
if exist result.txt del result.txt
)

set cnt=1
set err_cnt=0
for /F "delims=" %%i in (list1.txt) do (
call set /p<NUL=[%%cnt%%]
fc /n /w "%x%%%i" "%y%%%i" >> nul
if ERRORLEVEL 1 (
call echo [%%cnt%%] "%x%%%i" >> result.txt
fc /n /w "%x%%%i" "%y%%%i" 2>&1 >> result.txt
set /a err_cnt=err_cnt+1
)
set /a cnt=cnt+1
)

echo;

if %err_cnt%==0 (
set /p z="両者は完全に一致しました。"
) else (
set /p z="%err_cnt% 個が一致しませんでした。"
)
goto :EOF

:SUB
set A=%~1
call echo %%A:%~2=%%>>%3
goto :EOF

投稿日時 - 2018-10-13 21:37:03

お礼

教えていただきましたコードで
( )がある場合も!がある場合もうまくいきました!
また、このコードから、%の数や"の有無など
よく分からなかったことがとても参考になりました。
ありがとうございました。

投稿日時 - 2018-10-14 17:54:35

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

質問1:括弧内で閉じ括弧という文字を使うには" "で囲む必要があります。
あるいは、事前に ) を ^) に置換しておく。

質問2:!j:!x!=! は、j: という環境変数の値、xという1文字、= という環境変数の値 を並べたものですよ。

質問3:enabledelayedexpansionをすると ! を扱えません。

こんな感じでしょうか。
@echo off
set x=D:\temp\sample\DATA(1)_SP\
set y=D:\temp\sample\DATA(2)_SP\

if exist list1.txt del list1.txt
if exist list2.txt del list2.txt

dir /b /s /a-d "%x%" > list01.txt
dir /b /s /a-d "%y%" > list02.txt

for /F "delims=" %%i in (list01.txt) do (
echo %%~nxi>> list1.txt
)

for /F "delims=" %%i in (list02.txt) do (
echo %%~nxi>> list2.txt
)

fc /n /w list1.txt list2.txt > result.txt

if ERRORLEVEL 1 (
set /p z="両者は一致しませんでした。"
goto :EOF
) else (
if exist result.txt del result.txt
)

set cnt=1
set err_cnt=0
for /F "delims=" %%i in (list1.txt) do (
call set /p<NUL=[%%cnt%%]
fc /n /w "%x%%%i" "%y%%%i" >> nul
if ERRORLEVEL 1 (
call echo [%%cnt%%] "%x%%%i" >> result.txt
fc /n /w "%x%%%i" "%y%%%i" 2>&1 >> result.txt
set /a err_cnt=err_cnt+1
)
set /a cnt=cnt+1
)

echo;

if %err_cnt%==0 (
set /p z="両者は完全に一致しました。"
) else (
set /p z="%err_cnt% 個が一致しませんでした。"
)

投稿日時 - 2018-10-13 19:12:22

お礼

回答ありがとうございます。

>質問1:
>括弧内で閉じ括弧という文字を使うには" "で囲む必要があります。
>あるいは、事前に ) を ^) に置換しておく。

dir /b /s /a-d %x% > list01.txt
の部分は"%x%"としなくても正しく処理されていますが、
echo !j:%x%=!>> list1.txt
の部分でおかしくなっているようなので、
echo !j:"%x%"=!>> list1.txt
としてみたのですがうまくいきませんでした。
(echo !j!>> list1.txtのように処理されてしまっています)


>質問2:!j:!x!=! は、j: という環境変数の値、xという1文字、= という環境変数の値
>を並べたものですよ。

遅延環境変数を使わなければ
%j:%x%=%
なので、
遅延環境変数を使った場合でも、
環境変数jの文字列の中にある環境変数xの文字列を空白に置換する
という意味になると思っていたのですが
このようにはならないのでしょうか。
例えば、jがABCDEでxがBCDの時は、
%j:%x%=%はAEになると思いますが
!j:!x!=!ではAEにならないのでしょうか。


>質問3:enabledelayedexpansionをすると ! を扱えません。

それで遅延環境変数を使わない方法で対処されたわけですね。

教えて頂きましたコードを実行してみたのですが、
こちらではうまくいきませんでした。
例えば、
D:\temp\sample\DATA(1)_SPのフォルダの中に
!ABCとDEFというフォルダがあってこの中にファイルがある場合、
つまり
D:\temp\sample\DATA(1)_SP\!ABC\file001.exe
D:\temp\sample\DATA(1)_SP\DEF\file002.exe
D:\temp\sample\DATA(2)_SP\!ABC\file001.exe
D:\temp\sample\DATA(2)_SP\DEF\file002.exe
のような場合、うまくいきますでしょうか。

よろしくお願いします。

投稿日時 - 2018-10-13 20:42:48

あなたにオススメの質問