2013-03-14 3 views
0

Я знаю, что есть такие вопросы, как это раньше, но в моем случае есть особые условия при указании файлов, которые должны быть исключены в операции «удалить».Как удалить все файлы, но исключая определенные файлы (пакетный файл)

примеры Имя файла:

A_001.xml
A_002.xml
B_001.xml
B_002.xml
B_003.xml
C_009.xml
D_002.xml

Файлы выше, находятся в одном каталоге, и мне нужно удалить все файлы, но сохранить одну копию каждого файла с наивысшим счетчиком в имени файла A_002.xm, B_003.xml, C_009.xml и D_002.xml.

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

ответ

1
@ECHO OFF 

SETLOCAL enabledelayedexpansion 
:: 
:: establish target directory 
:: initialise PREFIX to a name that's invalid in a filename 
:: 
SET target=. 
SET prefix=: 
FOR /f "tokens=1*delims=_" %%i IN (
'dir /b/a-d/o-n "%target%\*_*.xml' 
) DO (
IF !prefix!==%%i ECHO DEL "%target%\%%i_%%j" 
SET prefix=%%i 
) 

Данное решение основано на наличии «_» в именах * xml-файлов в целевом каталоге. Я испытал это на некоторых фиктивных файлы в моем каталоге пакетной разработки, поэтому я использовал . для the current directory

Команда DIR выдает список файлов в целевом каталоге, которые соответствуют шаблону *_*.xml Переключатель /b означает filename only, /a-d средства no directory names, even if they match и /o-n означает in the reverse order of name Следовательно, имена будут отображаться с наивысшим числовым значением детали после _.

Цикл FOR читает этот вывод и присваивает префикс %%i и оставшуюся часть файла на %%j Так как prefix инициализируется к инвалидному-в-имена файлов характера, он не может соответствовать %%i для первого найденного файла, поэтому DEL не будет выполняться. Затем будет сохранен последний встречный префикс. Только если следующее имя файла имеет соответствующий префикс, будет выполнено DEL

Обратите внимание, что я вставил ключевое слово ECHO перед номером DEL. Это устройство безопасности в случае ошибки. ПРЕДВАРИТЕЛЬНАЯ ПРОГРАММА DEL будет представлена ​​на экране, а не ВЫПОЛНЯЕТСЯ. Как только вы убедитесь, что партия правильная, удалите ECHO, и операция удаления продолжится.

Точка наблюдается:

  • Некоторые редакторы довольно бесцеремонно о зачистки или удерживающее задней пространства. Обычно это безопасно, но конечные пробелы в команде SET могут привести к хаосу.
+0

Чтобы избежать проблем с помощью пробелов, вы можете просто заключить аргумент 'set' в кавычки:' set 'target =. "'. Любые конечные пробелы после этого не будут частью значения переменной. – Joey

+0

Да - вы также можете заключить в скобки SET '(set var = whatever)', который я обычно делаю, когда важно удалить переменную '(set var =)', но я чувствую, что она обычно переполняется. Возможно, я должен явно использовать форму ремней и брекетов, где это критически важно. Вы только когда-нибудь попадаете в эту конкретную ловушку, хотя, если это происходит более одного раза, возможно, вам стоит подумать о том, чтобы изменить свое занятие, а не просто ваш редактор ... – Magoo

+0

... или язык;) Хотя я нахожу его иногда приятным хобби, чтобы попытаться написать надежные и надежные пакетные файлы. – Joey

1
@echo off 
SETLOCAL ENABLEDELAYEDEXPANSION 
set newprefix=_ 
for /F %%a in ('dir /on /b /a-d *.xml') do (
for /F "delims=_" %%i in ("%%a") do (
    IF NOT *%%i*==*!newprefix!* (
    for /F %%q in ('dir /on /b /a-d %%i*.xml') do set lastitem=%%q 
    attrib +r !lastitem! > NUL 
    del /s /q %%i*.xml 1>NUL 2>NUL 
    attrib -r !lastitem! > NUL 
    set newprefix=%%i 
    ) 
) 
) 

Для каждого префикса XML-файл, перечислен все файлы с префиксом в вопросе, чтобы получить последнюю в списке. Затем отметьте последний только для чтения. Удалите все с заданным шаблоном, за исключением чтения. Сбросьте флаг только для чтения и перейдите для следующего префикса.

+0

Большое спасибо joojaa за ваш ответ. Я пометил ваш ответ как полезный, но, к сожалению, я должен выбрать ответ Питера как мой принятый ответ для более четкого объяснения и более простого кода. Еще раз спасибо mate :) – hisoka21

+0

Конечно, проблем нет, однако я считал, что не публиковать сценарий, так как Питер уже отправил ответ. Просто, что я чувствую, что Питер не ответил на вопрос напрямую. Код Peters использует только то, что не удаляет наибольшее число, так же, как я делаю с 4 строками во внутреннем цикле (используя трюк). Однако он не занимается автоматическим поиском каждого набора и его обработкой. Так что, хотя красиво аннотированный, на самом деле не отвечает на заданный вопрос. поскольку вам по-прежнему необходимо исправить префикс и так далее для каждой группы. Но это также причина, по которой я не хочу подробно комментировать задачу. – joojaa

Смежные вопросы