厳密にファイル名について、2つのフォルダを比較したいと思います。 (ファイルの内容ではない)。 Windows 10を使用していて、コマンドラインツールを使用したいと考えています。
これは問題を説明するかもしれないシナリオです。
Folders
-------
source source2
- file_1 - file_1
- file_2 - file_2
- file_3 - file_4
- file_5 - file_5
- file_6 - file_7
Output should be:
-----------------
Source -> Missing files file_4
Source2 -> Missing files file_3
いくつか調査しましたが、diff
ツールはたくさんありますが、ファイルの内容を比較することには興味がありません。 2つのフォルダーを比較し、両方のフォルダーで欠落しているファイルを(他のフォルダーと比較して)出力するだけです。
Powershellを使用したくない
ありがとうございました。
robocopy
(最近のWindowsバージョンに含まれています)は、これを1つのパスで実行できます。
\source\
と\source2\
を指定し、いくつかの一般的なファイルとどちらかのフォルダにのみ存在するファイルを実行
robocopy source source2 /L /NJH /NJS /NP /NS
収量
D:\Users\me\test\source\
*EXTRA Datei only_in_source2.txt
Neue Datei only_in_source.txt
ここで、*
で始まる行はsource2
(OS言語に依存しない)でのみファイルを示し、他の行はsource
でのみファイルを示します。
オプションはさまざまな出力項目を抑制し、/L
は相違点のみがリストされ、コピーされないように注意します。
次のコードをccomp.cmd
として保存し、/?
フラグを付けて呼び出して、その使用方法を確認します(Windows 7、Windows 10でテスト済み):
構文:
ccomp <dir_tree1> <dir_tree2>
コード:
@echo off
if "!ERRORLEVEL!" == "%ERRORLEVEL%" (
REM if delayed expansion is enabled:
(
echo.
echo ERROR: This script must be called in a Disabled Delayed Expansion block ^(default^)^^^!
echo.
call :PressAKey "Press a key to exit..."
echo.
)>con
exit /b 1
)
setlocal disabledelayedexpansion
if defined _first_time goto :label1MAIN
REM Test CHCP:
chcp /?>nul 2>nul||(
(
echo. & echo ERROR: Could not start chcp ^(necessary^)!
)>con
exit /b 1
)
REM Get the initial code page:
call :GetCurrentCodePage _initial_CP
REM Change the code page (character encoding) for "CON" (console) to 65001 (UTF-8):
set _con_error=false
mode con cp select=65001>nul 2>nul||(
(
echo. & echo WARNING: Could not change the code page for CON ^(Console^)!
)>con
set _con_error=true
)
set _help_flag=0
set /a _count=1
set "_script_path=%~Dpnx0"
:repeat1MAIN
if _%1_ == _""_ (
REM "%1" is """"
set _param%_count%=""
shift
set /a _count+=1
goto :repeat1MAIN
) else (
if /i "%~1" == "/?" (
set _help_flag=1
shift
goto :repeat1MAIN
) else (
if /i "%~1" == "/help" (
set _help_flag=1
shift
goto :repeat1MAIN
) else (
if /i "%~1" == "/h" (
set _help_flag=1
shift
goto :repeat1MAIN
) else (
if not "%~1" == "" (
REM if "%1" is null, it means that no more parameters are provided
set "_param%_count%=%~1"
shift
set /a _count+=1
goto :repeat1MAIN
)
)
)
)
)
set /a _count-=1
set /a _param_count=_count
REM start Checking parameters \/
if "%_help_flag%" == "1" (
call :DisplayHelp
exit /b 0
) else (
if %_param_count% gtr 2 (
(
echo. & echo ERROR: Too many parameters!
)>con
exit /b 1
) else (
if %_param_count% lss 2 (
(
echo. & echo ERROR: Too few parameters!
)>con
exit /b 1
)
)
)
set "_error=false"
if "%_param1%" == """" (
(
echo. & echo ERROR: First provided directory parameter must not be empty!
)>con
set "_error=true"
) else (
call :TestIfDirAcccessible _param1 _is_param1_dir
setlocal enabledelayedexpansion
if not "!_is_param1_dir!" == "0" (
endlocal
(
echo. & echo ERROR: First provided directory parameter: "%_param1%" is not a directory or is not accessible!
)>con
set "_error=true"
) else (
endlocal
)
)
if "%_param2%" == """" (
(
echo. & echo ERROR: Second provided directory parameter must not be empty!
)>con
set "_error=true"
) else (
call :TestIfDirAcccessible _param2 _is_param2_dir
setlocal enabledelayedexpansion
if not "!_is_param2_dir!" == "0" (
endlocal
(
echo. & echo ERROR: Second provided directory parameter "%_param2%" is not a directory or is not accessible!
)>con
set "_error=true"
) else (
endlocal
)
)
call :TestIfPathIsUNC _param1 _result1
call :TestIfPathIsUNC _param2 _result2
if "%_result1%" == "true" (
set "_error=true"
(
echo. & echo ERROR: Path1: "%_param1%" seems to be a UNC path ^(contains \\^), and UNC paths are not supported by this program ^(but a UNC path can be mounted ^(for example by using pushd^), in order to make it accessible^)!
)>con
)
if "%_result2%" == "true" (
set "_error=true"
(
echo. & echo ERROR: Path2: "%_param2%" seems to be a UNC path ^(contains \\^), and UNC paths are not supported by this program ^(but a UNC path can be mounted ^(for example by using pushd^), in order to make it accessible^)!
)>con
)
if "%_error%" == "true" (
(
echo. & call :PressAKey "Press a key to exit!"
echo.
)>con
exit /b 1
)
cmd /u /c ^(echo.^&echo Path1: "%_param1%"^)
cmd /u /c ^(echo.^&echo Path2: "%_param2%"^)
REM end Checking parameters /\
REM If everything seems ok, proceed to PROCESSING:
pushd "%_param1%\">nul
set "_param1=%CD%"
popd>nul
pushd "%_param2%\">nul
set "_param2=%CD%"
popd>nul
call :ConvertDriveLetterToUpperCase _param1 _param1
call :ConvertDriveLetterToUpperCase _param2 _param2
call :GetStrLen _param1 _param1_len
call :GetStrLen _param2 _param2_len
pushd "%_script_path%\..">nul
if not defined _first_time (
call :EscapePathString _script_path _script_path_escaped
call :EscapePathString _param1 _param1_escaped
call :EscapePathString _param2 _param2_escaped
)
popd>nul
REM Change the code page (character encoding) for "CON" (console) to 437 (ANSI):
if "%_con_error%" == "false" (
mode con cp select=437>nul 2>nul
)
:label1MAIN
REM CHCP 437 = ANSI CODE PAGE
REM CHCP 65001 = UTF-8 CODE PAGE
if not defined _first_time (
set _first_time=defined
chcp 65001>nul
cmd /u /c ^(echo.^&echo Start time: %date% %time%^&echo.^)
cmd /u /c ^(for /f ^"tokens=^*^" %%l in ^(^'^^^( setlocal^^^&^^^"%%_script_path_escaped%%^^^" ^^^"%%_param1_escaped%%^^^" ^^^"%%_param2_escaped%%^^^"^^^&title Sorting Results ^^^^^^^^^^^^^^^(finally^^^^^^^^^^^^^^^)^^^&endlocal ^^^)^^^|sort^'^) do @^(if not defined _once ^( set "_once=defined"^&echo %%l^) else echo %%l ^)^)^&if defined _once echo.
set "_first_time="
set "_second_time="
set "_third_time="
cmd /u /c ^(call echo End time: %%date%% %%time%%^)
chcp 437>nul
REM Restore the initial code page:
chcp %_initial_CP%>nul 2>nul
) else (
if not defined _second_time (
set _second_time=defined
(
call :ProcedureAnalyzeFiles
)
) else (
if not defined _third_time (
set "_third_time=defined"
(
call :ProcedureProcessFilenameLengthAndSize1
chcp 65001>nul
call :ProcedureProcessFilenameLengthAndSize2
chcp 437>nul
@REM After sorting: "-" is displayed in front of all other characters:
@call echo ----------------------------------------""%%_count1%%""
@title Sorting results. Please wait...
)
)
)
)
endlocal & (
if defined _first_time set "_first_time=%_first_time%"
if defined _second_time set "_second_time=%_second_time%"
if defined _third_time set "_third_time=%_third_time%"
)
goto :eof
REM \\\/// Next subroutines use jeb's syntax for working with delayed expansion: \\\///
:GetStrLen - by jeb - adaptation
(
setlocal EnableDelayedExpansion
set "s=!%~1!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
set "%~2=%len%"
exit /b
)
:EscapePathString
(
setlocal EnableDelayedExpansion
set "string=!%~1!"
call :GetStrLen string string_len
set /a string_len-=1
for /l %%i in (0,1,!string_len!) do (
rem escape "^", "(", ")", "!", "&"
if "!string:~%%i,1!" == "^" (
set "result=!result!^^^^"
) else (
if "!string:~%%i,1!" == "(" (
set "result=!result!^^^("
) else (
if "!string:~%%i,1!" == ")" (
set "result=!result!^^^)"
) else (
if "!string:~%%i,1!" == "^!" (
set "result=!result!^^^!"
) else (
if "!string:~%%i,1!" == "&" (
set "result=!result!^^^&"
) else (
if "!string:~%%i,1!" == "%%" (
set "result=!result!%%"
) else (
set "result=!result!!string:~%%i,1!"
)
)
)
)
)
)
)
)
(
endlocal
set "%~2=%result%"
exit /b
)
:TestIfDirAcccessible
(
setlocal EnableDelayedExpansion
set _returned_code=0
(pushd "!%~1!">nul 2>nul||set "_returned_code=1")&&popd>nul
)
(
endlocal
set "%~2=%_returned_code%"
exit /b
)
:TestIfPathIsUNC
(
setlocal EnableDelayedExpansion
set "_current_path=!%~1!"
set "_is_unc_path=true"
if "!_current_path:\\=!" == "!_current_path!" (
set "_is_unc_path=false"
)
)
(
endlocal
set "%~2=%_is_unc_path%"
exit /b
)
:GetCurrentCodePage
(
setlocal EnableDelayedExpansion
set "_current_cp=-1"
for /f "tokens=1,2* delims=:" %%a in ('chcp 2^>nul') do (
set "_current_cp=%%~b"
)
)
(
endlocal
set "%~1=%_current_cp%"
exit /b
)
:ConvertDriveLetterToUpperCase
(
setlocal EnableDelayedExpansion
set "_path=!%~1!"
for /f "tokens=1 delims=\" %%f in ('echo "!_path!"') do set "_path_drive=%%~df"
set "_upper_drive=!_path_drive!"
for %%D in (A: B: C: D: E: F: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: W: X: Y: Z:) do (
if /i "!_path_drive!" == "%%D" (
set "_upper_drive=%%D"
goto :endConvertDriveLetterToUpperCase
)
)
)
:endConvertDriveLetterToUpperCase
(
endlocal
set "%~1=%_upper_drive%%_path:~2%"
exit /b
)
REM ///\\\ The subroutines above use jeb's syntax for working with delayed expansion: ///\\\
:GenerateShortName
@set "%~1=%~s2"
@goto :eof
:GenerateShortNameSize
@set "%~1=%~z2"
@goto :eof
:ProcedureAnalyzeFiles
setlocal
for /f "tokens=1,2,3,4,5* delims=/" %%p in ('chcp 65001^>nul^&^(setlocal^&^"%_script_path_escaped%^" ^"%_param1_escaped%^" ^"%_param2_escaped%^"^|sort^&endlocal^)^&chcp 437^>nul') do (
if not defined _second_time_for1 (
set /a _total_count=%%~p>nul 2>nul
set /a _currrent_count=1
set _second_time_for1=defined
) else (
set /a _current_count+=1
REM START PROCESSING:
setlocal enabledelayedexpansion
title Analyzing file !_current_count! of !_total_count!...
set "_previous_file=!_current_file!"
set "_previous_file_type=!_current_file_type!"
set "_previous_file_visibility=!_current_file_visibility!"
set "_previous_file_dir=!_current_file_dir!"
REM Due to a bug in sort, an extra " is added at the end of the line, so we need to remove it:
set "_previous_file_size=!_current_file_size:"=!"
set "_previous_file_base_dir=!_current_file_base_dir!"
setlocal disabledelayedexpansion
set "_current_file=%%~p"
set "_current_file_type=%%~q"
set "_current_file_visibility=%%~r"
set "_current_file_dir=%%~s"
set "_current_file_size=%%~t"
setlocal enabledelayedexpansion
if "!_current_file_dir!" == "1" (
endlocal
set "_current_file_base_dir=%_param1%"
) else (
if "!_current_file_dir!" == "2" (
endlocal
set "_current_file_base_dir=%_param2%"
) else (
endlocal
)
)
setlocal enabledelayedexpansion
REM Due to a bug in sort, an extra " is added at the end of the line, so we need to remove it:
set "_current_file_size=!_current_file_size:"=!"
REM if not first time:
if NOT "!_previous_file_type!" == "" (
if "!_next!" == "1" (
if "!_current_file_type!" == "!_previous_file_type!" (
if "!_current_file_type!" == "file" (
if NOT "!_current_file!" == "!_previous_file!" (
echo Only in "!_previous_file_dir!" - !_previous_file_type!: "!_previous_file_base_dir!!_previous_file!"
) else (
set "_for_one_cannot_get_size=0"
if "!_previous_file_size!" == "-1" set "_for_one_cannot_get_size=1"
if "!_current_file_size!" == "-1" set "_for_one_cannot_get_size=1"
if "!_for_one_cannot_get_size!" == "0" (
if "!_previous_file_size!" GTR "!_current_file_size!" (
echo "!_previous_file_base_dir!!_previous_file!" ^(!_previous_file_dir!^) size ^(!_previous_file_size!B^) is bigger than "!_current_file_base_dir!!_current_file!" ^(!_current_file_dir!^) size ^(!_current_file_size!B^)
) else (
if "!_previous_file_size!" LSS "!_current_file_size!" (
echo "!_previous_file_base_dir!!_previous_file!" ^(!_previous_file_dir!^) size ^(!_previous_file_size!B^) is smaller than "!_current_file_base_dir!!_current_file!" ^(!_current_file_dir!^) size ^(!_current_file_size!B^)
)
)
)
)
) else (
if NOT "!_current_file!" == "!_previous_file!" (
echo Only in "!_previous_file_dir!" - !_previous_file_type!: "!_previous_file_base_dir!!_previous_file!"
)
)
) else (
echo Only in "!_previous_file_dir!" - !_previous_file_type!: "!_previous_file_base_dir!!_previous_file!"
)
)
)
endlocal
endlocal
endlocal
setlocal enabledelayedexpansion
if "%%~s" == "1" (
endlocal
set "_current_file_base_dir=%_param1%"
) else (
if "%%~s" == "2" (
endlocal
set "_current_file_base_dir=%_param2%"
) else (
endlocal
)
)
set "_temp=%%~p"
setlocal enabledelayedexpansion
REM if not first time:
if NOT "!_current_file_type!" == "" (
if "!_next!" == "1" (
if "%%~q" == "!_current_file_type!" (
if "!_temp!" == "!_current_file!" (
endlocal
set _next=2
) else (
endlocal
set _next=1
)
) else (
endlocal
set _next=1
)
) else (
endlocal
set _next=1
)
) else (
endlocal
set _next=1
)
set "_current_file=%%~p"
set "_current_file_type=%%~q"
set "_current_file_visibility=%%~r"
set "_current_file_dir=%%~s"
set "_current_file_size=%%~t"
)
)
REM Treat the last file separately:
chcp 65001>nul
setlocal enabledelayedexpansion
if "!_next!" == "1" (
echo Only in "!_current_file_dir!" - !_current_file_type!: "!_current_file_base_dir!!_current_file!"
)
endlocal
chcp 437>nul
endlocal
goto :eof
:ProcedureProcessFilenameLengthAndSize1
@setlocal
@set /a _count1=0
@REM Process directories:
@chcp 65001>nul
@title Loading directory paths for directory 1. Please wait...
@pushd "%_param1%">nul
@for /r /d %%f in (*) do @(
@set "_current_path=%%~f"
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@set /a _count1+=1 >nul
@setlocal enabledelayedexpansion
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param1_len%!///dir///1///1///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param1_len%!///dir///1///1///!_size!"
) else (
@echo "!_current_path:~%_param1_len%!///dir///1///1///-1"
)
)
@endlocal
)
@popd>nul
@title Please wait...
@REM Process directories:
@title Loading directory paths for directory 2. Please wait...
@pushd "%_param2%">nul
@for /r /d %%f in (*) do @(
@set "_current_path=%%~f"
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@set /a _count1+=1 >nul
@setlocal enabledelayedexpansion
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param2_len%!///dir///1///2///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param2_len%!///dir///1///2///!_size!"
) else (
@echo "!_current_path:~%_param2_len%!///dir///1///2///-1"
)
)
@endlocal
)
@popd>nul
@title Please wait...
@REM Process files:
@title Loading file paths for directory 1. Please wait...
@pushd "%_param1%">nul
@for /r %%f in (*) do @(
@set "_current_path=%%~f"
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@set /a _count1+=1 >nul
@setlocal enabledelayedexpansion
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param1_len%!///file///1///1///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param1_len%!///file///1///1///!_size!"
) else (
@echo "!_current_path:~%_param1_len%!///file///1///1///-1"
)
)
@endlocal
)
@popd>nul
@title Please wait...
@REM Process files:
@title Loading file paths for directory 2. Please wait...
@pushd "%_param2%">nul
@for /r %%f in (*) do @(
@set "_current_path=%%~f"
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@set /a _count1+=1 >nul
@setlocal enabledelayedexpansion
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param2_len%!///file///1///2///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param2_len%!///file///1///2///!_size!"
) else (
@echo "!_current_path:~%_param2_len%!///file///1///2///-1"
)
)
@endlocal
)
@popd>nul
@title Please wait...
@chcp 437>nul
@endlocal & (
@set _count1=%_count1%
)
@goto :eof
:ProcedureProcessFilenameLengthAndSize2
@setlocal
@REM Process hidden directories:
@for /f "tokens=*" %%f in ('title Loading hidden directory paths for directory 1. Please wait...^&@pushd "%_param1%"^>nul^&^&dir /a:dh /s /b 2^>nul^&^&popd^>nul^&title Please wait...') do @(
@set "_current_path=%%~f"
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@set /a _count1+=1 >nul
@setlocal enabledelayedexpansion
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param1_len%!///dir///0///1///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param1_len%!///dir///0///1///!_size!"
) else (
@REM This file is hidden an probabilly has a Unicode path:
@echo "!_current_path:~%_param1_len%!///dir///0///1///-1"
)
)
@endlocal
)
@title Please wait...
@REM Process hidden directories:
@for /f "tokens=*" %%f in ('title Loading hidden directory paths for directory 2. Please wait...^&@pushd "%_param2%"^>nul^&^&dir /a:dh /s /b 2^>nul^&^&popd^>nul^&title Please wait...') do @(
@set "_current_path=%%~f"
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@set /a _count1+=1 >nul
@setlocal enabledelayedexpansion
@set /a _count1+=1 >nul
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param2_len%!///dir///0///2///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param2_len%!///dir///0///2///!_size!"
) else (
@REM This file is hidden an probabilly has a Unicode path:
@echo "!_current_path:~%_param2_len%!///dir///0///2///-1"
)
)
@endlocal
)
@title Please wait...
@REM Process hidden files:
@for /f "tokens=*" %%f in ('title Loading hidden file paths for directory 1. Please wait...^&@pushd "%_param1%"^>nul^&^&dir /a:-dh /s /b 2^>nul^&^&popd^>nul^&title Please wait...') do @(
@set "_current_path=%%~f"
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@set /a _count1+=1 >nul
@setlocal enabledelayedexpansion
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param1_len%!///file///0///1///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param1_len%!///file///0///1///!_size!"
) else (
@REM This file is hidden an probabilly has a Unicode path:
@echo "!_current_path:~%_param1_len%!///file///0///1///-1"
)
)
@endlocal
)
@title Please wait...
@REM Process hidden files:
@for /f "tokens=*" %%f in ('title Loading hidden file paths for directory 2. Please wait...^&@pushd "%_param2%"^>nul^&^&dir /a:-dh /s /b 2^>nul^&^&popd^>nul^&title Please wait...') do @(
@set "_current_path=%%~f"
@set /a _count1+=1 >nul
@if "%%~zf" == "" (
@call :GenerateShortName _short_name "%%~f"
@call :GenerateShortNameSize _size "%%_short_name%%"
)
@setlocal enabledelayedexpansion
@title Processing file !_count1!...
@if not "%%~zf" == "" (
@echo "!_current_path:~%_param2_len%!///file///0///2///%%~zf"
) else (
@if not "!_size!" == "" (
@echo "!_current_path:~%_param2_len%!///file///0///2///!_size!"
) else (
@REM This file is hidden an probabilly has a Unicode path:
@echo "!_current_path:~%_param2_len%!///file///0///2///-1"
)
)
@endlocal
)
@title Please wait...
@endlocal & (
@set _count1=%_count1%
)
@goto :eof
:DisplayHelp
echo.
echo %~n0 ^(Cmd COMPare^) - Compare two directory trees by file and folder paths and by size
echo.
echo Syntax: %~n0 ^<dir_tree1^> ^<dir_tree2^>
echo.
echo - where ^<dir_tree1^> and ^<dir_tree2^> are two directory trees to be compared, provided by the user
echo.
echo * Note 1:
echo - Files that are hidden and also have a Unicode path - are compared only by path, not also by size
echo - In some rare cases ^(for some Unicode file paths^) some files may be misreported
echo.
echo * Note 2:
echo - This program uses the ^"sort^" utility for sorting results, so the waiting time for the comparison of the two directories depends on (is a multiple of) n * log n ^(the time complexity for the quick sort algorithm ^(used in ^"sort^"^)^) - where - n is the total number of files in the two directories that are to be compared.
echo - The output of the program is Unicode
echo.
echo Written by: Ioan Marin
goto :eof
:PressAKey
set /p=%~1<nul
pause>nul
goto :eof
両方のフォルダーのdir /b /A-d
ofをファイルに対して実行し、これらをfindstrおよび/VG:
オプションと比較します
サンプルツリーが与えられた場合:
> tree /f
X:.
│
└───Folders
├───source
│ file_1
│ file_2
│ file_3
│ file_5
│ file_6
│
└───source2
file_1
file_2
file_4
file_5
file_7
次のバッチファイル:
:: Q:\Test\2019\02\19\SU_1407481.cmd
@echo off
Set "DirA=X:\Folders\source\"
Set "DirB=X:\Folders\source2\"
Dir /B /A-D "%DirA%*" >DirA.txt
Dir /B /A-D "%DirB%*" >DirB.txt
echo file(s) missing in %DirA%
findstr /VG:DirA.txt DirB.txt
echo fil(e) missing in %DirB%
findstr /VG:DirB.txt DirA.txt
この出力を生成します:
> SU_1407481.cmd
file(s) missing in X:\Folders\source\
file_4
file_7
file(s) missing in X:\Folders\source2\
file_3
file_6
このPowershellスクリプトはあなたが望むことをします。
$fso = Get-ChildItem -Recurse -path C:\Temp\Source
$fsoBU = Get-ChildItem -Recurse -path C:\Temp\Source2
Compare-Object -ReferenceObject $fso -DifferenceObject $fsoBU
これと他のいくつかのオプションについては、ここで説明します。 https://stackoverflow.com/questions/3804109/what-is-the-best-way-to-compare-2-folder-trees-on-windows