Пакетный скрипт для поиска повторяющихся имен файлов в одном словаре

#windows #batch-file #cmd #duplicates

#Windows #пакетный файл #cmd #дубликаты

Вопрос:

Мне нужно найти файлы с одинаковыми именами в одном каталоге, распечатать их имена и вернуть некоторый код ошибки. На данный момент он работает нормально, но имена файлов печатаются несколько раз. Я сделал это довольно примитивным способом.

fol2 содержит файлы:

 Abc123
BBBB
CCCC
CCCCaaa
CCCCbbb
CCCCrrr
  

Мой вывод:

 CCCCaaa
CCCCbbb
CCCCrrr
CCCC
CCCCbbb
CCCCrrr
CCCC
CCCCaaa
CCCCrrr
CCCC
CCCCaaa
CCCCbbb
  

Ожидаемый результат:

 CCCCaaa
CCCCbbb
CCCCrrr
CCCC
  

Мой код:

 @ECHO Off
SetLocal EnableDelayedExpansion

    for /R C:UsersoperatorDesktopbatchfol2 %%a in (*.*) do (

        set fileDic1=%%~nxa
        set fileConcatPart1Dic1=!fileDic1:~0,3%!
        set fileConcatPart2Dic1=!fileDic1:~3%!
    
        for /R C:UsersoperatorDesktopbatchfol2 %%b in (*.*) do (
    
            set fileDic2=%%~nxb
            set fileConcatPart1Dic2=!fileDic2:~0,3%!
            set fileConcatPart2Dic2=!fileDic2:~3%!
            REM echo !fileConcatPart1Dic1!
            REM echo !fileDic2!
            if !fileConcatPart1Dic1!==!fileConcatPart1Dic2! (if not !fileConcatPart2Dic1!==!fileConcatPart2Dic2! (echo %%~nxb)) 
        
        )

    )
  

Я знаю, что появлялись похожие темы, но я хочу оценить свой код и получить совет о том, как сделать это другим, лучшим и, возможно, более простым способом.

Комментарии:

1. Первый совет, который я бы вам дал, — использовать модификаторы расширения для переменных. Вы можете просмотреть доступные из них, прочитав для вывода из for /? , в окне командной строки. Это означает, что вместо использования somevariablei=!anothervariablei:~0,3%! для части с буквой диска и somevariablei=!anothervariablei:~3%! для всех, кроме части с буквой диска, вы могли бы использовать somevariablei=%%~da и somevariablei=%%~pa вместо.

2. Я не понимаю, что вы пытаетесь сделать. Почему у вас есть два вложенных цикла, повторяющихся по одному и тому же дереву каталогов? Почему вы отделяете первые три символа каждого имени файла и проверяете их на равенство, а остальные проверяете на неравенство?

Ответ №1:

 @ECHO Off
SetLocal EnableDelayedExpansion

:: remove variables starting #
FOR  /F "delims==" %%a In ('set # 2^>Nul') DO SET "%%a="


    for /R C:UsersoperatorDesktopbatchfol2 %%a in (*.*) do (

        set fileDic1=%%~nxa
        set fileConcatPart1Dic1=!fileDic1:~0,3%!
        set fileConcatPart2Dic1=!fileDic1:~3%!
    
        for /R C:UsersoperatorDesktopbatchfol2 %%b in (*.*) do (
    
            set fileDic2=%%~nxb
            set fileConcatPart1Dic2=!fileDic2:~0,3%!
            set fileConcatPart2Dic2=!fileDic2:~3%!
            REM echo !fileConcatPart1Dic1!
            REM echo !fileDic2!
            if !fileConcatPart1Dic1!==!fileConcatPart1Dic2! if not !fileConcatPart2Dic1!==!fileConcatPart2Dic2! if not defined #%%~nxb (
               echo %%~nxb
               set "#%%~nxb=Y"
            ) 
        
        )

    )
  

Это должно сработать для вас.

Изменения таковы:
for /f...set # ... который должен удалять любые переменные, начинающиеся с # , из среды (вряд ли какие-либо, но это гарантирует)
, удалил круглые скобки вокруг if not... условия — вы можете каскадировать if операторы, если вы не используете else предложения.
Добавлен третий if , чтобы определить #%%~nxb , была ли установлена переменная. если он не установлен, то он будет установлен при редактировании имени echo . Поскольку затем он устанавливается (на непустое значение), он не not defined пройдет тест, и, следовательно, имя не будет повторяться.