#batch-file
#пакетный файл
Вопрос:
for /f %%a in ('type "file.txt"^|find "" /v /c') do set /a count=%%a
Я нашел эту команду здесь http://www.dostips.com/?t=Snippets .Количество строк
Кажется, это работает, но я не могу понять, почему. Я неохотно использую что-то, чего я не понимаю, если только в нем нет ошибки для специальных символов и т. Д. Но я не могу понять, почему это работает.
Комментарии:
1. Введите
find /?
из командной строки и прочитайте, что/v
/c
делают переключатели and .2. Насколько вы знакомы с batch? Ответ будет меньше, если мне не нужно объяснять, что
for /f
делает цикл.3. Открутите команду.
type "c:windowswin.ini" |find "" /v /c
4. Было бы полезно, если бы вы сказали нам, какую часть вы не понимаете. Если вы не понимаете
for
, у нас проблема.5. Ну, с одной стороны, я тоже этого не понял, а потом заметил, что это batch , а не bash .
Ответ №1:
Наизнанку
type file.txt
просто прочитайте файл и выведите его содержимое в стандартный вывод.- В этом коде выходные
type
данные команды передаются по конвейеру вfind
команду. find
Команда считывает стандартный ввод (не указан файл для чтения) и фильтрует его, ища строки, которые ничего не содержат (/v
) (ничегоfind
не соответствует, если указана пустая строка). Во время фильтрации он подсчитает, сколько найдено строк, и выведет в стандартный поток только количество совпадающих строк (/c
). Поскольку пустая строка ничему не соответствует, но/v
переключатель отрицает ее, мы заканчиваем сопоставление (и подсчет) всех строк в файле.- Две предыдущие переданные по каналу команды выполняются с помощью
for /f
команды.for /f
используется для обработки строки, чтения содержимого файла или выполнения команды и обработки ее выходных данных.
примечание: по умолчанию команда, которая должна быть выполнена, заключена в одинарные кавычки в in
предложении for /f
команды
примечание: канал — это специальный символ, и чтобы включить его в for /f
команду, нам нужно экранировать его ( ^|
)
- Для каждой строки (строки, каждой строки внутри файла или каждой строки в выходных данных команды) выполняется код внутри
do
предложения, при этом обрабатываемая строка (или некоторые ее части) сохраняется вfor
заменяемом параметре (%%a
в этом коде) - Выходные
find
данные команды (количество строк в файле) сохраняются в параметреfor /f
replacable ,do
предложение выполняется, и количество строк в файле (сохраненное в параметре replacable) копируется в переменную среды
примечание: set /a
используется для арифметических операций. В данном случае в этом нет необходимости, и простая set
команда должна выполнить всю работу, но, возможно, она была написана таким образом, чтобы было понятнее, что значение, которое будет сохранено в переменной среды, является числом
Комментарии:
1. «возможно, это было написано так, чтобы сделать его более понятным» — Да, или чтобы заставить его быть числом (0), если вывод по какой-то причине не числовой.
2. @GolezTrol, переменные среды всегда являются строками,
/a
просто вызывает отдельный анализатор для обработки арифметики, чего нет в этом коде. Я до сих пор не виделfind /c
, чтобы команда выводила какие-либо цифры, вы знаете, как это сделать?3. Да, переменные среды всегда являются строками, но
set /a var=XYZ
приводит к превращению в var0
. Таким образом, вы могли бы использовать/a
здесь как приведение к типу, гарантируя, что var будет содержать «число» (строку, содержащую допустимое числовое значение) вместо текстового значенияXYZ
, которое может прервать следующий шаг. Это может быть использовано в качестве меры предосторожности или как способ облегчить проверку результата на следующем этапе. Обычно это должно работать, но я могу себе представить, чтоfind
может вернуть что-то еще в случае ошибки (файл нечитаемый, время ожидания сети и т. Д.).4. Хорошо, быстрый тест показывает, что это действительно должно всегда работать и
type "file.txt"^|find "" /v /c
вернет ошибку, за которой следует 0, когда файл не найден, так что, возможно, эта мера предосторожности в конце концов не нужна. Но, возможно, автор этого кода этого не знал. 😉5. @GolezTrol
find
выводит ошибки в stderr (не считываетсяfor /f
командой). Нет возможности ошибки файлаfind
, поскольку он не считывает ни один файл, кроме передаваемых данных. Если полная внутренняя команда завершается с ошибкой и нет выходныхdo
данных, предложение не выполняется, а переменная пуста (инициализации нет), или может быть извлечена строка, соответствующая другой переменной, и сгенерировать неправильное значение, или она может сгенерировать математическую ошибку, сбой и не инициализировать переменную, …есть способы, при которых это может привести к сбою, ноset /a
это не гарантирует отсутствия сбоя и здесь не требуется .