#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
пройдет тест, и, следовательно, имя не будет повторяться.