Пакетный скрипт, который проверяет каталог на наличие дубликатов файлов - PullRequest
0 голосов
/ 23 мая 2018

Попытка просмотреть файл, например,

C: \ Users \ Admin \ Desktop \ Test \ 12345

C: \ Users \ Admin \ Desktop \ Test \45635

C: \ Users \ Admin \ Desktop \ Test \ 12345-2018-04-21

, создайте подпапку с именем «12345» и в ней будут храниться два файла (12345и 12345-2018-04-21) в подпапке "12345".и это будет перебирать всю папку, чтобы убедиться, что нет копий

:: ---------------------------------------------------------------
:: - This is a program that searches for files with the same 5 
::   digit number and puts them in a subfolder.
:: ---------------------------------------------------------------
@ECHO off

SETLOCAL
SET "sourcedir=C:\Users\Admin\Desktop\Test"
SET "destdir=C:\Users\Admin\Desktop\Test"
SET /a lastnum=200000

if "%first5%" equ "%lastnum%"(
SET "destdir=%destdir%\%first5%-sub"
 md %destdir%
)

FOR /f "delims=" %%a IN (
 'dir /b /a-d /on "%sourcedir%\*" '
 ) DO (
 CALL :detect "%%a"
 IF DEFINED dupnum (ECHO(MOVE "%sourcedir%\%%a" "%destdir%\")
)

GOTO end 

:: Routine to detect whether the first 5 characters of the filename "%1"
:: are all numeric and if so, whether they match the previous 5-digit number
:: found.

:detect
SET "dupnum="
:: Get the first 5 characters of the filename; prefix with a `1`
SET "fullfilename=%~1"
SET "first5=1%fullfilename:~0,5%"
IF "%first5%" neq "%lastnum%" (
 SET "lastnum=%first5%"
   GOTO end
)
:: First 5 chars of this filename = first 5 of previous filename
:: Check to see whether numeric
SET /a dummy=first5 + 0
IF "%dummy%" neq "%first5%" (
 SET "lastnum=%first5%"
   GOTO end 
)
SET "dupnum=Y"
   GOTO end 

ENDLOCAL

:end

PAUSE

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

1 Ответ

0 голосов
/ 24 мая 2018

Трудно определить, с чего начать, если вы раньше не сталкивались с языком.

Первая проблема - правильно указать, что означают ваши термины.Например, «дублированный файл» обычно означает дубликат содержимого или дубликат имени (но поскольку каталог может содержать только один файл с любым конкретным именем, это подразумевает разные каталоги).В вашем случае ваше индивидуальное определение - это «файлы, имена которых начинаются с тех же 5 цифр».

Поскольку это приводит к пакету, в котором используется много методов (и может быть много подходов)тогда это то, что можно использовать:

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET /a lastnum=200000

md %destdir% 2>nul

FOR /f "delims=" %%a IN (
 'dir /b /a-d /on "%sourcedir%\*" '
 ) DO (
 CALL :detect "%%a"
 IF DEFINED dupnum (ECHO(MOVE "%sourcedir%\%%a" "%destdir%\")
)

GOTO :EOF

:: Routine to detect whether the first 5 characters of the filename "%1"
:: are all numeric and if so, whether they match the previous 5-digit number
:: found.

:detect
SET "dupnum="
:: Get the first 5 characters of the filename; prefix with a `1`
SET "fullfilename=%~1"
SET "first5=1%fullfilename:~0,5%"
IF "%first5%" neq "%lastnum%" (
 SET "lastnum=%first5%"
 GOTO :eof
)
:: First 5 chars of this filename = first 5 of previous filename
:: Check to see whether numeric
SET /a dummy=first5 + 0
IF "%dummy%" neq "%first5%" (
 SET "lastnum=%first5%"
 GOTO :eof
)
SET "dupnum=Y"
GOTO :eof

Вам нужно изменить настройки sourcedir и destdir в соответствии с вашими обстоятельствами.

Требуемые команды MOVE простоECHO ed для тестирования. После того, как вы убедились, что команды верны , измените ECHO(MOVE на MOVE, чтобы фактически переместить файлы.Добавьте >nul для подавления сообщений отчета (например, 1 file moved)

По сути, пакетный код нечувствителен к регистру с заметным исключением metavariable в операторе for (%%a выше)

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

Обычно предполагается, что пакетный код запускается из приглашения, а не путем «щелчка».

Синтаксис SET "var=value" (где значение может быть пустым) используется, чтобы гарантировать, что любые паразитные пробелы НЕ включены вприсвоенное значение.set /a обычно можно использовать без кавычек.

Оператор @echo off отключает отображение команд, поэтому команда не выводится на консоль перед выполнением.

Оператор setlocal вызывает «локальное окружение», поэтому любые изменения или дополнения к окружению удаляются по завершении пакета.

Основной цикл сначала выполняет команду dir, чтобы создатьсписок каталогов.Выбранные параметры: /b - базовый (без верхнего / нижнего колонтитула - только имена) /a-d - без имен каталогов и /on - порядок по имени (т. Е. В алфавитном порядке)

Вывод * 1054Команда * затем обрабатывается for /f с параметром "delims=".Это присваивает всю строку metavariable %%a.

Для каждого найденного имени файла выполняется подпрограмма :detect.Поскольку эта процедура находится в этом пакетном файле, в выражении call используется :.Без : подпрограмма call ed была бы пакетным файлом с именем detect (либо detect.bat или detect.cmd, причем более популярным является первый)

После того, как подпрограмма :detect былавыполняется, переменная с именем dupnum может быть или не быть установлена.Если установлено, echo строка.Если нет, не надо.

Процедура :detect сначала "устанавливает" s dupnum (результат процедуры) в пустую строку, которая удаляет переменную из среды, если она существует.

Переменная fullfilename затем устанавливается на значение, переданное из оператора call.%1 означает «первый параметр».%~1 означает «и заключить в кавычки».Кавычки необходимы для того, чтобы передаваемое имя файла содержало пробелы.

Затем мы получаем первые 5 символов из полного имени файла (из «символа 0» для 5 символов) и добавляем префикс 1.Пакетная обработка строки, которая начинается с 0 как восьмеричная строка, если используется в математической операции, поэтому префикс 1 гарантирует, что теперь 6 символов будут интерпретированы как десятичные.

Теперь - если first5 не равно lastnum, то мы записываем новые lastnum и goto :eof, которые выходят из подпрограммы.dupnum не установлен, поэтому вызывающий цикл не будет показывать это имя файла.

Далее, мы хотим сделать движение, только если первые 5 (ну, теперь 6) символов все числовые.Мы можем добавить 0 к строке в математическом режиме, используя set /a, что приведет либо к тому же числу (если эти символы являются полностью числовыми), либо к другому числу (до первого не числового), если«first5» содержит нечисловые значения.

Итак, проверьте результат - если он отличается, «first5» содержит нечисловые значения, поэтому выручите, если dupnum не установлено.Если то же самое, тогда установите dupnum, чтобы сообщалось имя файла.

Обратите также внимание, что официальная инструкция примечание имеет вид rem, но :: (что является неправильной меткой).- тот, который не может быть достигнут) часто используется вместо замечаний, поскольку его легче набирать и менее навязчивым для глаз.Обратите внимание, что стиль :: нельзя использовать в пределах code-block s (операторы сгруппированы в скобках)


Я добавил новую строку md ..., которая должна создать каталог назначения,2>nul подавляет сообщения об ошибках, если этот каталог уже существует.Если вы хотите, чтобы этот каталог был подкаталогом исходного каталога, то установите destdir таким образом:

set "destdir=%sourcedir%\subdirectorynamedesired"
...