1

Будучи не очень хорошим в DOS-скрипте, но имело хорошее применение, я нашел здесь много простых решений проблем, с которыми я сталкиваюсь. Итак, недавно я скопировал здесь форму скрипта, чтобы подсчитать количество файлов в подкаталогах. Я немного изменил его, чтобы соответствовать моей цели. Теперь он выглядит следующим образом и отлично работает на моем рабочем столе, где я его написал:

FOR /D %%D IN ("*") DO (
  FOR /F %%K IN ('DIR /A-D "%%D" 2^>NUL ^| FIND "File(s)" ^|^| ECHO 0') DO (
    ECHO %%D: %%K
  )
)

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

Все машины работают под управлением Windows 7 (профессиональная на той, которая имеет значение, на двух других используется премиум или профессиональная).

Что здесь происходит и как мне это исправить?

Спасибо!

2 ответа2

0

Установлен или изменен язык отображения Windows. Ваш сценарий зависит от языка. Например, команда dir показывает статистику как Soubor(ů) вместо File(s) в чешских окнах.

dir |find "Files(s)" затем устанавливает %ERRORLEVEL% в 1:

FIND установит %ERRORLEVEL% следующим образом:

  • 0 Строка найдена хотя бы в одном из файлов;
  • 1 строка не найдена;
  • 2 Если какие-либо файлы в списке не существуют или файлы не соответствуют маске подстановочного знака. Указан неверный переключатель.

И обратите внимание, что «Файл (ы)» является допустимым именем папки; следовательно, ваш скрипт может показать

==>md "File(s)"

==>D:\bat\SU\935171.bat
a b: 3
File(s): Directory
FooBar: 0
FooFoo: 4
0

С тем же подходом

@echo off
    setlocal enableextensions disabledelayedexpansion

    for /d %%a in (*) do for /f "tokens=1,5" %%b in ('
        dir /a-d "%%~fa\*" 2^> nul ^| findstr /b /c:"  " ^|^| echo 0
    ') do if "%%c"=="" echo %%~fa : %%b

Это будет

  • Для каждой папки (for /d) возьмите ссылку и сохраните ее в %%a заменяемый параметр
  • Запустите команду dir указав полный путь к папке %%~fa
  • Используйте трубу (|) для фильтрации списка, чтобы получить только строки, начинающиеся с двух пробелов (строки нижнего колонтитула)
  • Если строки не найдены (то есть команда dir не выполнена), выведите 0
  • Линии, сгенерированные dir | findstr обрабатывается командой for /f . Мы прочтем первый токен (количество файлов в просчитанной строке) и пятый (только в строке нижнего колонтитула с информацией о каталогах)
  • Если пятый элемент пуст, в этой строке есть информация о файлах, а не о папках, поэтому выведите путь к папке и файлам внутри нее.

Проблема с этим подходом состоит в том, что dir | findstr выполняется для каждой из подпапок. Для более быстрого решения

robocopy . . /l /nocopy /is /e /nfl /lev:2 /njh /njs

Это просто вызовет robocopy , но вместо того, чтобы что-то копировать, мы будем просить, чтобы ничего не копировалось, и возвращать только список того, что должно быть обработано (/nocopy /l). Мы просим скопировать из текущей папки в текущую папку, включая идентичные файлы в процессе (/is), обрабатывая пустую подпапку (/e , чтобы включить папки с 0 файлами), но обрабатывать только два уровня (/lev:2 the текущая папка и папка ниже), без создания списка файлов (/nfl), без заголовка задания (/njh) и без сводки задания (/njs)

Результатом будет тот же список, но с именем папки и количеством файлов в измененных столбцах.

Сохранить исходный формат вывода

@echo off
    setlocal enableextensions disabledelayedexpansion

    for /f "tokens=1,*" %%a in ('
        robocopy . . /l /nocopy /is /e /nfl /lev:2 /njh /njs
    ') do echo %%~fb : %%a

Это будет использовать for /f для обработки предыдущей команды robocopy , разделив строку на два токена, первый будет содержать количество файлов и будет сохранен в %%a , а второй - оставшуюся часть строки и будет сохранен в %%b . Для каждой строки в выходных данных внутренней команды robocopy выполняется код в предложении do : просто введите echo, чтобы отобразить два токена в обратном порядке.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .