Ответы пользователя по тегу cmd/bat
  • Как исправить странные символы вместо русских букв в путях при выполнении командного файла?

    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 Ошибка!

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

    wisgest
    @wisgest
    Не ИТ-специалист
    Использовать цикл с ключом /D:
    for /d %%D in (C:\1\*) do move "%%D" C:\2\
    Ответ написан
    1 комментарий