Поиск файлов и возвращение имени родительского каталога с большинством совпадений? - PullRequest
0 голосов
/ 27 октября 2019

Скажем, у меня есть поисковая маска типа "*casting?00*", которая должна соответствовать каталогу в дереве по количеству совпадений с именами файлов. Как я могу вернуть только подкаталог с большинством совпадений имен файлов

Ответы [ 2 ]

2 голосов
/ 27 октября 2019

Рекурсивно зацикливать подпапки, подсчитывать соответствующие файлы в каждой (сохранить их во временный файл для дальнейшей обработки). Сортируйте его и получите последнюю строку, разделяя счетчик и имя папки:

@echo off
setlocal enabledelayedexpansion
del tmp.csv 2>nul
for /r /d %%a in (*) do (
set "count="
  for /f %%b in ('dir /b "%%a\*casting?00*" 2^>nul ^|find /c /v ""') do (
  set "count=    %%b"
  echo !count:~-4!,%%a >>tmp.csv
     )
)

sort tmp.csv

for /f "tokens=1,* delims=, " %%a in ('sort tmp.csv') do set "folder=%%b" & set "count=%%a"
echo --- %count% findings in %folder% ---

Примечание. Если несколько папок имеют одинаковый макс. количество подходящих файлов, это даст вам только последний.

Редактировать , чтобы использовать массив вместо файла (на мой взгляд, менее читабелен, но просто чтобы показать, как он можетбыть сделано):

@echo off
setlocal enabledelayedexpansion
set index=0
for /r /d %%a in (*) do (
  set "count="
  set /a index+=1
  for /f %%b in ('dir /b "%%a\*casting?00*" 2^>nul ^|find /c /v ""') do (
    set "count=    %%b"
    set "Array[!index!]=!count:~-4!,%%a
  )
)
set Array
for /f "tokens=1,* delims=, " %%x in (
    '(for /f "tokens=2 delims==" %%a in ('set Array'^) do @echo %%a^)^|sort'
  ) do set "count=%%x" & set "folder=%%y"
echo --- %count% findings in %folder% ---
0 голосов
/ 28 октября 2019

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

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

Существует множество "ошибок". Что в значительной степени всегда верно в CMD. Специальные символы вызовут проблемы. С помощью метода, который я покажу, символы ", =, ] и [ определенно вызовут проблемы. Другой проблемой является длина командной строки и длина имени переменной. Если ваши пути будут очень длинными, тогда этот код захлебнется. Я думаю это где-то около 8000.

Как правило, чтобы отсортировать числа по алфавиту, вы должны дополнить их начальными символами (обычно нулями или пробелами). Когда числа будут произвольными и инкрементальными, я предпочитаю начинать с большого числа, например, 10000 вместо 0 или 1. В этом сценарии я не использую инкрементные числа, а вместо этого использую счетчик файлов в качестве псевдо-числа. индекс. Я предпочитаю математику дополнению нулями, поэтому я просто добавляю 1 000 000 к счету. Это будет держать его в алфавитном порядке до тех пор, пока в любой подпапке будет 8,999,999 файлов или меньше. Я почти уверен, что максимальная вероятность в математических ограничениях CMD будет начинаться с 1 000 000 000, что позволяет использовать около 1 147 483 648 файлов.

@echo off

setlocal enabledelayedexpansion

:: Just in case there are any array variables already defined
:: we'll clear them first.
for /f "delims==" %%a in ('set a1 2^>nul') do set %%a=
for /f "delims==" %%a in ('set a2 2^>nul') do set %%a=

for /r /d %%a in (*) do (
   for /f %%b in ('dir /b "%%a\*casting?00*" 2^>nul ^|find /c /v ""') do (
      set /a filecount=%%b + 1000000
      set "a1[!filecount!]%%~pnxa=%%b"
      set "a2[%%~a]=%%b"
   )
)

:: Things you can do with this . . .

:: Basic list in order from largest count to smallest
set a1|sort /r

:: List the "first" folder with the most files
echo.
echo The "first" folder with the most files:
for /f "tokens=2 delims==]" %%a in ('set a1 ^| sort /r') do echo %%a & goto :continue

:continue

:: The largest file count
echo.
for /f "tokens=2 delims=[]" %%a in ('set a1 ^| sort /r') do (
   set /a maxfiles = %%a - 1000000
   echo The most files in any subfolder is !maxfiles!.
   goto :continue
)

:continue

:: All of the subfolders that share the max number of files:
echo.
echo.
echo.
for /f "tokens=2 delims=[]=" %%a in ('set a1 ^| sort /r') do (
   set /a maxfiles = %%a - 1000000
   echo All the subfolders with the maximum of !maxfiles! files . . .
   for /f "tokens=2 delims==]" %%b in ('set a1[%%a]') do echo.  %%b
   goto :continue
)

:continue

:: The subfolders with 0 files
echo.
echo.
echo.
echo The subfolders with 0 files . . .
for /f "tokens=2 delims==]" %%a in ('set a1[1000000] 2^>nul') do (
   set nonempty=yes
   echo.  %%a
)
if not defined nonempty echo.  There are none.

:: CSV style output
echo.
echo.
echo.
for /f "tokens=2,3 delims=]=" %%a in ('set a1 ^| sort /r') do echo "%%a",%%b

Массив a2 здесь не используется, а лишь пример сопоставления массива, расположенного по-другому.

...