みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

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

解決済みの質問

DOSバッチでフォルダ配下の全ファイルの一致確認

Windowsのコマンドプロンプトのバッチファイルで
2つのフォルダの配下にあるファイルがすべて完全に
一致することを確認するバッチファイルを作成しています。

下記のようなコードまではできたのですが、
現状ではコードの「pause」の所で、
一度、止めて、人が、
list1.txtのファイルから環境変数xの文字列
(ここではC:\document\A\)
list2.txtのファイルから環境変数yの文字列
(ここではC:\document\B\)
を削除して保存し直してから続行しないと
うまくいきません。

回避策として、pauseの所で、
list1.txtのファイルを1行ずつ読み込んで
環境変数xの文字列を空白文字に置換して
上書き保存する。
list2.txtのファイルを1行ずつ読み込んで
環境変数yの文字列を空白文字に置換して
上書き保存する。
ということをしたいのですが、

(方法1)
set 環境変数=%環境変数:置換前文字列=置換後文字列%
の置換前文字列を環境変数%x%で指定することが
できないようなのでうまくいきません。

(方法2)
環境変数xの文字列の文字数を環境変数lenに入れて
set 環境変数=%環境変数:~開始文字位置,文字数%
の開始文字位置を環境変数%len%で指定することが
できないようなのでうまくいきません。

何かよい方法はないでしょうか。


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

rem 以下の2行を実行前に書き換える
set x=C:\document\A\
set y=C:\document\B\

set w=FC: 相違点は検出されませんでした
set w=%w:~0,18%
set v=*****
set v=%v:~0,5%

if exist list1.txt del list1.txt
if exist list2.txt del list2.txt
if exist huichi1.txt del huichi1.txt
if exist huichi2.txt del huichi2.txt

dir /b /s /a-d %x% > list1.txt
dir /b /s /a-d %y% > list2.txt

pause

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

for /F "delims=" %%i in (huichi1.txt) do (
set j=%%i
set j=!j:~0,18!
if !j!==!w! goto OK1
)
set /p z="両者は一致しませんでした。huichi1.txtを確認してください。"
goto END

:OK1

for /F "delims=" %%i in (list1.txt) do (
fc /n /w "%x%%%i" "%y%%%i" >> huichi2.txt
)

set u=0
for /F "delims=" %%i in (huichi2.txt) do (
set j=%%i
set j=!j:~0,5!
if !j!==!v! set u=1
)

if %u%==0 (
set /p z="両者は完全に一致しました。"
) else (
set /p z="両者は一致しませんでした。huichi2.txtを確認してください。"
)

:END
------------------------------------

【条件】
 ・Wondows7のコマンドプロンプトで実行する。
 ・他のツール(perlなど)は使用しない。
 ・test.batは
  set x=C:\document\A\
  set y=C:\document\B\
  の部分のみをその都度書き換えて使用する。

よろしくお願いします。

投稿日時 - 2018-01-05 19:58:37

QNo.9415243

困ってます

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

バッチファイルでは、全ての文字を扱うのは無理です。
特殊文字ごとに特別対応が必要なケースもあります。

! はsetlocal enabledelayedexpansionをやめる
& はファイル名を引用符で囲む
で、可能ですが、list1.txt list2.txtに記録されるファイル名が引用符込みになります。
% を含むファイル名は駄目ですね。

@echo off

set x=C:\document\A\
set y=C:\document\B\

(for /f "delims=" %%F in ('dir /b /s /a-d %x%') do call :delx "%%F") > list1.txt
(for /f "delims=" %%F in ('dir /b /s /a-d %y%') do call :dely "%%F") > list2.txt

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

if ERRORLEVEL 1 (
set /p z="両者は一致しませんでした。huichi1.txtを確認してください。"
) else (
set /p z="両者は完全に一致しました。"
)
goto :EOF

:delx
set "F=%~1"
call echo "%%F:%x%=%%"
goto :EOF

:dely
set "F=%~1"
call echo "%%F:%y%=%%"
goto :EOF

投稿日時 - 2018-01-08 10:22:28

お礼

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

教えていただきましたコードで!や&があっても
ファイルのフルパスが一致していることが
確認できるようになりました。

このあとファイルの中身が一致することを確認したいので
引用符を取り外したいのですが
%%i
から先頭と末尾に付いている " を取り除くには
どのように記述すればよいのでしょうか。

下記のtest2.batのように
%%i:"=%%"
としてみたのですがうまくいきません。

よろしくお願いします。

---test2.bat---------------------------
@echo off

set x=C:\document\A\
set y=C:\document\B\

(for /f "delims=" %%F in ('dir /b /s /a-d %x%') do call :delx "%%F") > list1.txt
(for /f "delims=" %%F in ('dir /b /s /a-d %y%') do call :dely "%%F") > list2.txt

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

if ERRORLEVEL 1 (
set /p z="両者は一致しませんでした。huichi1.txtを確認してください。"
goto :EOF
)

set err=0
if exist huichi2.txt del huichi2.txt
for /F "delims=" %%i in (list1.txt) do (
fc /n /w "%x%%%i:"=%%" "%y%%%i:"=%%" >> huichi2.txt  <---- ???
if ERRORLEVEL 1 (
set err=1
)
)

if %err%==0 (
set /p z="両者は完全に一致しました。"
) else (
set /p z="両者は一致しませんでした。huichi2.txtを確認してください。"
)

goto :EOF

:delx
set "F=%~1"
call echo "%%F:%x%=%%"
goto :EOF

:dely
set "F=%~1"
call echo "%%F:%y%=%%"
goto :EOF
---------------------------------------

投稿日時 - 2018-01-08 20:25:18

ANo.2

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

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

回答(3)

ANo.3

> %%iから先頭と末尾に付いている " を取り除くにはどのように記述すればよいのでしょうか。

%%~i
ですね。

投稿日時 - 2018-01-08 20:46:26

お礼

なんとかできるようになりました。
ありがとうございました。

---test3.bat---------------------------------
@echo off

rem 以下の2行を実行前に書き換える(末尾に\をつけること)
set x=C:\Document\A\
set y=C:\Document\B\

if exist list1.txt del list1.txt
if exist list2.txt del list2.txt
if exist huichi1.txt del huichi1.txt
if exist huichi2.txt del huichi2.txt

echo 比較リスト作成中です・・・

(for /f "delims=" %%F in ('dir /b /s /a-d %x%') do call :delx "%%F") > list1.txt
(for /f "delims=" %%F in ('dir /b /s /a-d %y%') do call :dely "%%F") > list2.txt

echo 比較実行中です・・・

fc /n list1.txt list2.txt > huichi1.txt

if ERRORLEVEL 1 (
set /p z="両者は一致しませんでした。huichi1.txtを確認してください。"
goto :EOF
) else (
if exist huichi1.txt del huichi1.txt
)

for /F "delims=" %%i in (list1.txt) do (
fc /b "%x%%%~i" "%y%%%~i" > nul
if ERRORLEVEL 1 (
fc /b "%x%%%~i" "%y%%%~i" 2>&1 >> huichi2.txt
)
)

if exist huichi2.txt (
set /p z="両者は一致しませんでした。huichi2.txtを確認してください。"
) else (
set /p z="両者は完全に一致しました。"
)

goto :EOF

:delx
set "F=%~1"
call echo "%%F:%x%=%%"
goto :EOF

:dely
set "F=%~1"
call echo "%%F:%y%=%%"
goto :EOF
----------------------------------------------

投稿日時 - 2018-01-13 17:35:16

ANo.1

ファイル名の先頭を削除してから比較する。

@echo off
setlocal enabledelayedexpansion

set x=C:\document\A\
set y=C:\document\B\

(for /f "delims=" %%F in ('dir /b /s /a-d %x%') do call :delx "%%F") > list1.txt
(for /f "delims=" %%F in ('dir /b /s /a-d %y%') do call :dely "%%F") > list2.txt

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

if ERRORLEVEL 1 (
set /p z="両者は一致しませんでした。huichi1.txtを確認してください。"
) else (
set /p z="両者は完全に一致しました。"
)
goto :EOF

:delx
set F=%~1
echo !F:%x%=!
goto :EOF

:dely
set F=%~1
echo !F:%y%=!
goto :EOF

投稿日時 - 2018-01-06 18:23:44

お礼

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

教えていただきましたサンプルコードを実行すると
テストファイルでの比較は正しく行われましたが、
実際のデータで確認すると、あるところで
「・・・・は、内部コマンドまたは外部コマンド、
 操作可能なプログラムまたはバッチ ファイルとして
 認識されていません。」
というエラーで止まってしまいます。
いろいろ調べてみましたところ
ファイル名またはフォルダ名に
&が含まれているとうまくいかないようです。

また、元々のtest.batのコードでも、
ファイル名またはフォルダ名に
!が含まれていると、
list1.txtとlist2.txtの出力時に
!が空白に置き換わっていて
fcコマンド実行時にファイルが存在しない
というエラーになることも分かりました。

ファイル名またはフォルダ名に
&や!が含まれていても
正しく比較することができる
よい方法はないでしょうか。

よろしくお願いします。

投稿日時 - 2018-01-08 09:30:38

あなたにオススメの質問