Профиль пользователя заблокирован сроком с 5 мая 2024 г. и навсегда по причине: нарушение п. 5.3 и 5.7 правил сайта в профиле
Ответы пользователя по тегу cmd/bat
  • Как лучше всего хранить многострочный текст в .cmd или .bat файле?

    wisgest
    @wisgest
    Не ИТ-специалист
    Вкратце (возможно, когда-нибудь дополню ответ, если вспомню какие либо тонкости и соберусь с силами).

    Чтобы разбить команду на несколько строк надо в конце каждой строки добавить символ ^. Если после него будет идти пустая строка, то в команду будет вставлен перевод строки.

    Пример.
    echo ^
    Hello,^
    
        world!

    выведет
    Hello,
        world!

    Если использовать отложенное раскрытие переменных, то можно вывести текст, сохранённый в переменной:
    setlocal enabledelayedexpansion
    set A=^
    Hello,^
    
      world!
    echo !A!

    В тексте надо удваивать знаки процента, экранировать символом ^ специальные символы (его самого, символы перенаправления, соединения команд, закрывающую скобку (внутри составных команд), желательно, кавычку…), дважды экранировать восклицательные знаки при отложенном раскрытии переменных, если текст между ними может быть воспринят как имя переменной… В общем, упражняйтесь.

    Ещё можете посмотреть тему CMD/BAT: Возможность создания heredoc. Также, например, в теме CMD/BAT: Пакетные макросы с параметрами рассматривается создание переменных (CR и LF), содержащих символы перевода строки и возврата каретки:
    spoiler
    :: Определяет переменную ВОЗВРАТ КАРЕТКИ (используется как !CR!)
    for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
    
    :: Определяет переменную ПЕРЕВОД СТРОКИ (используется как !LF!)
    set LF=^
    
    
    :: Две пустые строки сверху важны - не удалять!
    Ответ написан
    Комментировать
  • Как исправить странные символы вместо русских букв в путях при выполнении командного файла?

    wisgest
    @wisgest
    Не ИТ-специалист
    Ваш командный файл был сохранён в кодировке UTF-8. Пересохраните его в кодировке DOS/OEM (для русской Windows — это cp866) или в начале самого командного файла с помощью команды chcp включите в консоли кодовую страницу кодировки, в которой он сохранён; для UTF-8 — 65001:
    chcp 65001
    (но в ранних выпусках cmd для Windows, по крайней мере до XP включительно, UTF-8 в командных файлах плохо поддерживалась).

    (Также можно кодовую страницу по умолчанию для консольных приложений, например, в данном случае cmd.exe, задать в реестре…)
    Ответ написан
    Комментировать
  • Как удалить переносы строк в файле?

    wisgest
    @wisgest
    Не ИТ-специалист
    Echo !St!>>"%NewFileName%" в любом случае вставляет перевод после выводимой строки. Чтобы этого не происходило, можно вместо echo использовать set /p с вводом из пустого устройства (forum.script-coding.com/viewtopic.php?id=2945):
    set /p =!St!<nul >>"%NewFileName%"
    Ответ написан
    Комментировать
  • Почему ругается на знак |?

    wisgest
    @wisgest
    Не ИТ-специалист
    Перед этим знаком стоит синтаксически незавершённая команда
    for /f "usebackq" %%a in (`echo %%h %%i
    так как, если так можно выразиться, приоритет этого знака выше чем у знака ` (но, например, ниже чем у неэкранированного знака ").
    Чтобы знак | стал частью команды, а не её ограничителем, его необходимо экранировать знаком ^.
    Ответ написан
    5 комментариев
  • Почему в батник не берет элементы из переменной?

    wisgest
    @wisgest
    Не ИТ-специалист
    Теоретическое обоснование и разбор всех случаев писать лень (возможно, когда-нибудь перепишу и дополню ответ).

    У вас точно не работает двукратное раскрытие переменных
    set "randomFile=!pyti_k_15_perebivkam[!randomIndex!]!"

    Не перепроверял, но попробуйте взамен
    call set "randomFile=!pyti_k_15_perebivkam[%%randomIndex%%]!"

    и поищите сведения об использовании команды call для отложенного раскрытия переменных, при котором могут быть свои трудности.
    Ответ написан
    Комментировать
  • Почему замена строк местами не работает на большом документе?

    wisgest
    @wisgest
    Не ИТ-специалист
    (Не очень понятно, в чём состоит «открытие файла на чтение»: по моему, просто присваивается значение одной переменной другой.)

    Вероятно, не хватает памяти для переменных окружения.
    Можно не запоминать все строки, а прочитать три первых, вывести их в нужном порядке, а затем выводить строки, не запоминая их, в новый файл и удалить старый.

    Первые три строки можно получить так:
    (
    set /p "s1="
    set /p "s2="
    set /p "s3="
    ) <input.txt

    Вывести содержимое файла, начиная с четвёртой строки можно, например, с помощью утилиты more:
    more +3 input.txt >>output.txt
    или
    more +3 <input.txt >>output.txt

    А в целом:
    (
    set /p "s1="
    set /p "s2="
    set /p "s3="
    echo !s3!
    echo !s2!
    echo !s1!
    more
    ) <input.txt >output.txt
    del input.txt
    ren output.txt input.txt

    В этом случае, возможно, вместо
    more
    для перехвата оставшихся строк будет лучше
    find /v ""
    Ответ написан
    3 комментария
  • Как убить процесс в названии коротого пробелы использую командную строку?

    wisgest
    @wisgest
    Не ИТ-специалист
    Как и во многих других случаях аргументов с пробелами использовать кавычки:
    taskkill /im "name with spaces.exe"
    Ответ написан
    Комментировать
  • Как переименовать все файлы в нижний регистр с помощью cmd?

    wisgest
    @wisgest
    Не ИТ-специалист
    Уточнение про NTFS и FAT32 (добавлено 2022-12-26)
    Условный
    for /f "Tokens=*" %f in ('dir /l/b/a-d') do (rename "%f" "%f")

    поэтому не срабатывает.

    Если бы это совсем не срабатывало, то вряд ли было бы выбрано лучшим ответом на соответствующий вопрос на Super User. У меня это срабатывает на NTFS, а вот на FAT32 (проверялось на съёмном USB-накопителе) — нет. Более того, на FAT32, если имя файла укладывается в формат 8.3, при попытке переименования (не обязательно с помощью CMD.EXE, можно и в Проводнике…), меняющем только регистр символов, все символы переводятся в верхний регистр!

    Вручную приходится делать Abc.jpg -> 1Abc.jpg -> abc.jpg

    Так что мешает делать это не вручную?
    Например, в теле цикла
    (ren "%f" "to_lower_%f" && ren "to_lower_%f" "%f")
    При этом, правда, будут впустую переименовываться туда-сюда файлы с именами уже в нижнем регистре. Чтобы этого избежать можно добавить перед телом цикла проверку for %g in ("%~nxf") do if not "%f"==%g:
    for /f "delims=" %f in ('dir /l/b/a-d') do  for %g in ("%~nxf") do  if not "%f"==%g  (ren "%f" "to_lower_%f" && ren "to_lower_%f" "%f")

    Прежний совет (до правки 2022-12-25)
    …Чтобы этого избежать можно сделать в командном файле так:
    for /f "delims=" %%f in ('dir /l/b/a-d') do  for %%g in ("%%f*") do (
    	if /i "%%f"=="%%g"  if not "%%f"=="%%g" (
    		ren "%%f" "to_lower_%%f" && ren "to_lower_%%f" "%%f"
    	)
    )

    И ещё: если обрабатываемая папка открыта в Проводнике, то, скорее всего (наблюдалось в случае NTFS), чтобы увидеть изменение регистра имён файлов, надо будет обновить содержимое окна.
    Ответ написан
  • Как массово переименовать файлы по порядку?

    wisgest
    @wisgest
    Не ИТ-специалист
    Переименование файлов в текущем каталоге будет выглядеть так:
    setlocal enableextensions enabledelayedexpansion
    set /a "num = 0"
    for %%I in (*.jpg) do (
    	set /a "num += 1"
    	ren "%%~I" !num!.ren_jpg
    )
    ren *.ren_jpg *.jpg
    endlocal
    Ответ написан
  • Как в bat файле удалить текущую директорию?

    wisgest
    @wisgest
    Не ИТ-специалист
    Что значит
    RD %cd% не удаляет
    ? — Должно же быть какое-то сообщение об ошибке, которое нужно привести в вопросе.

    Если в каталоге есть открытые файлы, он занят какими либо процессами или недостаточно прав для удаления каталога или файлов в нём, то естественно не удалит.

    Чтобы каталог не был занят самим процессом cmd.exe перейдите в надкаталог и удалите прежний рабочий каталог:
    for %%D in (.) do (cd ..& rd "%%~fD")
    или, если переменная среды CD не определена, используйте одноимённую псевдопеременную:
    cd ..& rd "%CD%"
    В обоих случаях требуется расширенная обработка команд (по умолчанию включена). Команда RD скорее всего потребует дополнительные ключи (/S и /Q).

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

    wisgest
    @wisgest
    Не ИТ-специалист
    1-й способ) Перенаправить вывод команды в файл и ввести переменную из этого файла:
    tasklist /fi "IMAGENAME eq vlc.exe" | find /c /i "vlc.exe">file.tmp
    set /p "VAR="<file.tmp
    del file.tmp

    2-й способ) Обработать в цикле с ключом /f вывод команды:
    for /f %%V in ('tasklist /fi "IMAGENAME eq vlc.exe" ^| find /c /i "vlc.exe"') do  set "VAR=%%V"

    (При этом не придётся создавать вспомогательный файл, но для выполнения команды будет запускаться дополнительный процесс cmd.exe.)
    Ответ написан
    2 комментария
  • Как добавить отметку времени в выводе команды ping?

    wisgest
    @wisgest
    Не ИТ-специалист
    Вывод команды ping перенаправляется на вход сложной команды.

    При перенаправлении ввода-вывода между командами (|) в cmd (сказанное не относится к перенаправлению в/из файл(а)), когда с какой-то из сторон стоит внутренняя или составная команда, для неё запускается отдельный процесс cmd.exe, поэтому лучше задать это явно, чтобы иметь возможность точно указать параметры его запуска, как мудро и проделано в рассматриваемом примере (но, похоже, забыли про обычно используемый в таких случаях ключ /d для отключения выполнения возможных команд из реестра при запуске нового процессаcmd).

    1. Как работает эта часть кода (pause&pause)>nul

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

    Вместо этого можно было без >nul использовать, например, две команды set /p, даже и не указывая перед знаком равенства имя переменной, в которую вводится строка.

    Добавлено: Как выяснилось при обсуждении вопроса, дело обстоит сложнее…

    2. Как работает эта часть set /p "data=" && echo(!date! !time! !data!)

    Очередная строка из входного потока вспомогательного процесса cmd, то есть из выходного потока ping, помещается (set /p) в переменную окружения data и в случае успеха (&&), за который считается то, что была введена непустая строка (иначе переменная окружения не изменяется), выполняется следующая команда echo, выводящая строку из разделённых пробелами псевдопеременных date, time и только что установленной переменной data.
    Псевдопеременные date иtime содержат текущие дату и время, но только если не определены одноименные переменные окружения, поэтому для учёта всех возможных случаев их следовало бы в начале явным образом сбросить.

    Имена переменных заключены в восклицательные знаки, а не знаки процента, для отложенного раскрытия изменяющихся переменных в команде повторения (цикле) , а не однократной подстановки их значений до выполнения цикла. Возможность использовать отложенное раскрытие в данном случае включается ключом /v команды cmd. (Возможно также для отложенного раскрытия использовать команду call…)

    Открывающая скобка сразу после echo — это не открывающая скобка составной команды, а разделитель между командой echo и её аргументом, а закрывающая скобка относится к составной команде в цикле for /l %a in () do.

    Зачем нужна команда ping -n 2 8.8.8.8>nul после бесконечного цикла, я не знаю и буду рад увидеть разъяснения этому.
    Добавлено: Но без неё изменяется формат вывода:
    7.10.2022 21:47:58,02 Ответ от 8.8.8.8:
    7.10.2022 21:47:58,04 число байт=32 время=244мс TTL=104
    7.10.2022 21:47:59,04 Ответ от 8.8.8.8:
    7.10.2022 21:47:59,04 число байт=32 время=240мс TTL=104
    7.10.2022 21:48:00,05 Ответ от 8.8.8.8:
    7.10.2022 21:48:00,05 число байт=32 время=233мс TTL=104


    Спасибо за интересный вопрос!
    Ответ написан
  • Как расставить приоритетность выполнения арифметических операций в bat?

    wisgest
    @wisgest
    Не ИТ-специалист
    Как уже сказал Sergei Nazarenko, можно экранировать скобки (достаточно закрывающие), но лучше взять выражение в кавычки. В set /a не следует без необходимости и понимания заключать имена переменных в знаки процента, так как в этом случае их значения будут подставлены до выполнения составной команды, что приведёт к ошибкам, например, в цикле.
    set /a "sum = (x + x) * c * x"
    или
    set /a sum = "(x + x) * c * x"
    Ответ написан
    Комментировать
  • Как из cmd открыть ссылку с автовыбором браузера?

    wisgest
    @wisgest
    Не ИТ-специалист
    Командой start:
    start https://qna.habr.com/q/1139478
    Ответ написан
    Комментировать
  • Как разделить xml файл спомощью bat/cmd?

    wisgest
    @wisgest
    Не ИТ-специалист
    Если файл будет иметь именно такой вид, то это просто (при этом будут потеряны пустые строки, если они есть):
    @echo off
    setlocal enableextensions enabledelayedexpansion
    
    :0
    if "%~1" == "" (
    	set /p in="Входной файл: "
    	call :0 !in!
    	exit /b
    )
    
    if not exist "%~1" (
    	echo "%~f1" не найден.
    	endlocal
    	exit /b 1
    )
    
    set /a i = 0
    for /f "usebackq skip=1 delims=" %%L in ("%~1") do  (
    	if "%%L" == "<post>"  (
    		set /a i += 1
    		(echo ^<?xml version="1.0" encoding="UTF-8"?^>)>!i!.xml
    	)
    	(echo(%%L)>>!i!.xml
    )
    endlocal

    — XML-формат не учитывается, идёт разделение по строкам <post>, которые должны начинаться с начала строки и не иметь пробелов в конце строки.
    Ответ написан
    8 комментариев
  • Как удалить префикс у всех файлов?

    wisgest
    @wisgest
    Не ИТ-специалист
    Если в пакетном файле, то можно
    ren "-@xxx*" "     *"
    for %%i in ("     *") do  for /f "tokens=*" %%j in ("%%i") do  ren "%%i" "%%j"

    — первой командой префикс заменяется пробелами (количество пробелов равно длине префикса, см. https://qna.habr.com/q/1059906#answer_2036902), а второй убираются пробелы.
    Ответ написан
  • Как с помощью for добиться такого же результата, что и командой dir?

    wisgest
    @wisgest
    Не ИТ-специалист
    Справку пробовали почитать: for /??

    Выводит папки и все файлы в папке в виде полного пути.

    Файлы— for с ключом /r. Если нужны подкаталоги, используйте ключи /d /r. В одном списке без перехвата вывода команды dir, скорее всего, нельзя.
    Ответ написан
    Комментировать
  • Как правильно экранировать строку?

    wisgest
    @wisgest
    Не ИТ-специалист
    В общем случае вопрос не такой уж простой.
    Первоначальный ответ без учёта того, что команды в скобках
    В данном случае можете заменить | на ^^^|:
    set LINE=block_image_update(map_partition("product_a"), package_extract_file("product.transfer.list"), "product.new.dat.br", "product.patch.dat") ^^^|^^^|	abort("E2001: Failed to update product image.");

    — экранируются | для set и ещё раз экранируются | и уже ^ для echo.

    В данном случае можно использовать отложенное раскрытие переменных и экранировать | и ):
    setlocal enabledelayedexpansion
    
    set s=1
    if %s% == 1 (
    
    set LINE=block_image_update(map_partition("product_a"^), package_extract_file("product.transfer.list"^), "product.new.dat.br", "product.patch.dat"^) ^|^|	abort("E2001: Failed to update product image."^);
    
    echo !LINE! >> file
    
    )
    Ответ написан
    2 комментария
  • Можно ли через cmd ограничить мощность CPU для php скрипта?

    wisgest
    @wisgest
    Не ИТ-специалист
    То, что вы написали, — параметры командной строки самого php и к cmd отношения не имеют. Обратитесь к документации по php.

    В cmd посмотрите на задание приоритета процесса при помощи команды start:
    LOW Запуск приложения с приоритетом IDLE.
    BELOWNORMAL Запуск приложения с классом приоритета BELOWNORMAL
    Ответ написан
    Комментировать
  • Как реализовать обработку исключений в CMD?

    wisgest
    @wisgest
    Не ИТ-специалист
    КОМАНДА1 && КОМАНДА2
    — вторая команда выполняется, если первая завершилась без ошибок.
    КОМАНДА1 || КОМАНДА2
    — вторая команда выполняется, если первая завершилась с ошибкой.

    КОМАНДА && echo Ошибок нет! || echo Ошибка!

    (Для объединения нескольких команд в составную можно использовать скобки, переносы строк или знак & между командами в одной строке. Для размещения одной простой команды на нескольких строках можно использовать ^ в конце переносимой строки…)
    Ответ написан
    Комментировать