解決済み

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

  • 困ってます
  • 質問No.9547120
  • 閲覧数115
  • ありがとう数2
  • 気になる数0
  • 回答数2
  • コメント数0

お礼率 88% (171/193)

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)
 

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

  • 回答No.2

ベストアンサー率 48% (4382/8998)

>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
お礼コメント
ID_20150222

お礼率 88% (171/193)

教えていただきましたコードで
( )がある場合も!がある場合もうまくいきました!
また、このコードから、%の数や"の有無など
よく分からなかったことがとても参考になりました。
ありがとうございました。
投稿日時 - 2018-10-14 17:54:35
たいせつな将来のこと。あえて、知らない人に聞いてみよう。

その他の回答 (全1件)

  • 回答No.1

ベストアンサー率 48% (4382/8998)

質問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% 個が一致しませんでした。"
)
お礼コメント
ID_20150222

お礼率 88% (171/193)

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

>質問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
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,500万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する

特集


OKWAVE若者応援スペシャル企画

ピックアップ

ページ先頭へ