<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; CMD/BAT]]></title>
		<link>https://forum.script-coding.com/index.php</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;fid=18&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние темы раздела «Серый форум».]]></description>
		<lastBuildDate>Mon, 03 Aug 2026 07:50:27 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[CMD/BAT: (+JS) Демонстрация приёмов обработки текста, скачивание видео]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18616&amp;action=new</link>
			<description><![CDATA[<p>Писал уже на Хабре, скрипт обновляется периодически на GitHub, но как-то забыл опубликовать здесь - всё таки много полезного узнал в своё время на script-coding[.]info ещё, да и гибридные скрипты впервые здесь увидел. Задача в чём: нужно как можно быстрее скачать в нужном мне качестве видео посредством yt-dlp, проблема ещё в том, что с некоторых сайтов после редизайна стандартно не скачивает вообще. В общем нормальный батник, только &quot;продвинутая&quot; обработка текста передаётся js части скрипта, между ним и cmd частью организовано взаимодействие. Просто иллюстрация некоторых приёмов. Возможно, кому-то покажется интересным. Вот текущая версия скрипта:<br /></p><div class="codebox"><pre><code>
@set @x=0 /*
@echo off
chcp 65001 &gt;nul
setlocal
set VideoURL=https://smotrim.ru/brand/67607#playing_video=2627918
set head=
set suffix=
set series=%%(series)s. 
call :set_template
set format=b
set enable_format_recommendations=1
set extension=mkv
set AppPath=D:\kvk\Utilities\GitHub\yt-dlp\yt-dlp.cmd
if not exist %AppPath% set AppPath=yt-dlp.exe
if not -%1- == -- (set format=%1 &amp; set enable_format_recommendations=0)
set tempFileName=%random%.tmp
call %AppPath% -o &quot;%%template:.!=%%&quot; --windows-filenames --socket-timeout 45 --print-to-file filename %%tempFileName%% --skip-download %%VideoURL%%
if not errorlevel 0 if exist %tempFileName% del /q %tempFileName%
if exist %tempFileName% goto :normal_process
:: после редизайна сайта smotrim.ru
for /f &quot;tokens=1,2,3,4 delims=,&quot; %%i in (&#039;cscript /nologo /e:javascript &quot;%~dpnx0&quot; %tempFileName% /GetSmotrimData:&quot;%VideoURL%&quot;&#039;) do if not &quot;%%i&quot; == &quot;&quot; set new_url=&quot;%%i&quot;&amp;set id=%%j&amp;set json_url=%%k&amp;set duration=%%l
if not defined new_url exit /b
set /p title=&lt;%tempFileName%
set template=%head%%title% [+%id%]%suffix%.%extension%
if exist %tempFileName% del /q %tempFileName%
set filename=&quot;%template%.txt&quot;
echo %VideoURL% &gt; %filename%
echo. &gt;&gt; %filename%
echo %json_url% &gt;&gt; %filename%
echo %new_url% &gt;&gt; %filename%
set VideoURL=%new_url%
echo. &gt;&gt; %filename%
call %AppPath% --socket-timeout 45 --print formats_table %VideoURL% &gt;&gt; %filename%
cscript /nologo /e:javascript &quot;%~dpnx0&quot; %filename%
if -%1- == ---- exit /b
start &quot;yt-dlp: smotrim&quot; %AppPath% -k -o &quot;%template%&quot; --replace-in-metadata &quot;title&quot; &quot;playlist&quot; &quot;%title%&quot; --windows-filenames --remux-video %extension% --concurrent-fragments 10 --socket-timeout 45 --abort-on-unavailable-fragment --exec &quot;pause &quot; --embed-metadata --postprocessor-args &quot;Metadata+ffmpeg:-metadata duration_string=%duration%&quot; --format %format% %VideoURL%^&amp;exit/b
exit /b
:normal_process
cscript /nologo /e:javascript &quot;%~dpnx0&quot; %tempFileName%
set /p filename=&lt;%tempFileName%
set processed_series=%filename:!.=!%
if not &quot;%processed_series%&quot; == &quot;%filename%&quot; (setlocal enabledelayedexpansion &amp; set series=!series:~0,-2! &amp; setlocal disabledelayedexpansion &amp; call :set_template &amp; set filename=%processed_series%)
set filename_without_series=%filename:NA. =%
if not &quot;%filename_without_series%&quot; == &quot;%filename%&quot; (set series=&amp; call :set_template &amp; set filename=%filename_without_series%)
setlocal enabledelayedexpansion
set filename=!filename:.mp4=.%extension%!
set filename=!filename:.webm=.%extension%!.txt
setlocal disabledelayedexpansion
echo %VideoURL% &gt; &quot;%filename%&quot; &amp;&amp; del /q %tempFileName%
cscript /nologo /e:javascript &quot;%~dpnx0&quot; &quot;%filename%&quot;
call %AppPath% --socket-timeout 45 --print &quot;&lt;%%%%(webpage_url_domain)s:%%%%(uploader)s&gt;&quot; %%VideoURL%% &gt;&gt; &quot;%filename%&quot;
cscript /nologo /e:javascript &quot;%~dpnx0&quot; &quot;%filename%&quot; /toUTF-8:1
echo.&gt;&gt; &quot;%filename%&quot;
call :size &quot;%filename%&quot;
set tempsize=%filesize%
call %AppPath% --socket-timeout 45 --print formats_table %%VideoURL%% &gt;&gt; &quot;%filename%&quot;
if not errorlevel 0 exit /b
call :size &quot;%filename%&quot;
if %tempsize% == %filesize% exit /b
for /f %%i in (&#039;cscript /nologo /e:javascript &quot;%~dpnx0&quot; &quot;%filename%&quot; /FORMATRECOMMENDATIONS:%enable_format_recommendations%&#039;) do if defined enable_format_recommendations if &quot;%enable_format_recommendations%&quot; == &quot;1&quot; if not &quot;%%i&quot; == &quot;&quot; set format=%%i
if -%1- == ---- exit /b
rem --limit-rate 8.5M
start &quot;yt-dlp: %VideoURL%&quot; %AppPath% -k -o &quot;%template%&quot; --split-chapters --postprocessor-args &quot;SplitChapters+ffmpeg:-map_metadata -1&quot; --video-multistreams --audio-multistreams --windows-filenames --remux-video %extension% --concurrent-fragments 10 --socket-timeout 45 --abort-on-unavailable-fragment --exec &quot;pause &quot; --embed-metadata --format %format% %VideoURL% ^&amp;exit/b
:set_template
set template=%head%%series%%%(title)s [%%(id)s]%suffix%.%%(ext)s
exit /b
:size
set filesize=%~z1
goto:eof */

// Описание работы скрипта на основании подготовленного видео о скачивании с его помошью (с размышлениями о юридических тонкостях при этом),
// статьи в Дзене у меня, также текстов скриптов (там ещё про получение оглавления папки с видеофайлами)
// в Алисе Про: https://alicepro.yandex.ru/expert/projects/5f35ee4ef1a511f081018e7d0d775479
// (этот вариант описательного ИИ может использоваться только на территории Российской Федерации и Республики Беларусь)
// Ссылка на свежий вариант этого батника у меня на GitHub: https://kvk-2015.github.io/y.cmd
// У меня на компьютере установлена кодировка utf-8, если нужно, чтобы скрипт корректно выполнял поиск по регулярным выражениям на кирилице,
// сохраните его в кодировке Windows-1251, если она установлена на вашем компьютере

var fso = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;), fName = &quot;&quot;, newText = &quot;&quot;, WshShell = new ActiveXObject(&quot;WScript.Shell&quot;), url, id, json_url;
var CodePagesTestsDone = false, CodePages = [], q_mark = decodeURIComponent(&quot;%EF%BC%9F&quot;), re_process_marks = new RegExp(&quot;([!&quot; + q_mark + &quot;])\\.(\\s)&quot;, &quot;g&quot;);
var lines, lineIndex, line, oExec, double_quotes = decodeURIComponent(&quot;%EF%BC%82&quot;), colon = decodeURIComponent(&quot;%EF%BC%9A&quot;);
if(url=WSH.Arguments.Named.Item(&quot;GetSmotrimData&quot;)){var duration=&quot;&quot;;
    if(!/:\/\/smotrim\.ru.*\/.*video[\/=](\d+)$/.test(url))WSH.Quit();
    with(str=new ActiveXObject(&quot;ADODB.Stream&quot;)){Type=2; Mode=3;}
    oExec = WshShell.Exec((json_url=&#039;curl.exe --raw &quot;https://player-api.smotrim.ru/api/v1/video/&#039; + (id=RegExp.$1)) + &#039;&quot;&#039;);
    while(!oExec.Status || !oExec.StdOut.AtEndOfStream)lines = oExec.StdOut.ReadAll().replace(/([&quot;}\d\]]|null),([&quot;{\[])/g, &quot;$1,\n$2&quot;).split(&quot;\n&quot;);
    for(lineIndex in lines){
        line = lines[lineIndex];
        if(/&quot;title&quot;:\s*&quot;(.+)&quot;(?:,|$)/.test(line))newText += &quot;. &quot; + DosToWin(decodeURIComponent(encodeURIComponent(RegExp.$1)
            .replace(/(?:%EF%BF%BD){2}/g, &quot;..&quot;))).replace(/\?/g, q_mark).replace(/\\&quot;/g, double_quotes).replace(/:/g, colon);
        if(!new_url &amp;&amp; /&quot;m3u8&quot;:\s*&quot;(.*episode[^&quot;]+)&quot;/.test(line))var new_url = RegExp.$1;
        if(!duration &amp;&amp; /&quot;duration&quot;:\s*(\d+)/.test(line)){dI = parseInt(RegExp.$1, 10); var HH = Math.floor(dI/3600); dI -= HH * 3600;
            var MM = Math.floor(dI/60); dI -= MM * 60; duration = &quot;&quot; + HH + &quot;:&quot; + (&quot;0&quot; + MM).slice(-2) + &quot;:&quot; + (&quot;0&quot; + dI).slice(-2);
        }
    }
    if(new_url &amp;&amp; id &amp;&amp; json_url)WSH.echo(new_url + &quot;,&quot; + id + &quot;,&quot; + json_url.slice(16) + &quot;,&quot; + duration);
    if(newText)newText = newText.slice(2).replace(re_process_marks, &quot;$1$2&quot;);
}
if(WSH.Arguments.Unnamed.Count &amp;&amp; (fso.FileExists(fName=WSH.Arguments.Unnamed(0)) || newText)){
    if(1*WSH.Arguments.Named.Item(&quot;toUTF-8&quot;)){
        oExec = WshShell.Exec(&#039;reg.exe query &quot;HKLM\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage&quot; -v ACP&#039;);
        var Windows_codepage = getCodepageName(oExec);
    } else Windows_codepage = &quot;UTF-8&quot;;
    with(new ActiveXObject(&quot;ADODB.Stream&quot;)){Type=2; Mode=3;
        if(!newText){Open(); Charset=Windows_codepage; LoadFromFile(fName); Position=0; newText=ReadText().replace(/(?:\s*&lt;[^:]*:NA&gt;)?\s*$/g, &quot;&quot;); Close()}
        newText = ((isTemp=/^\d+\.tmp$/.test(fName)) ? newText.replace(/\(/g, &quot;{&quot;).replace(/\)/g, &quot;}&quot;) : newText.replace(/ *\r\n|\n(\r\n)?/g, &quot;\r\n$1&quot;));
        if(fso.FileExists(fName))fso.DeleteFile(fName);
        Open(); Charset=&quot;UTF-8&quot;; Position=0; WriteText(newText + (isTemp ? &quot;&quot; : &quot;\r\n&quot;)); SaveToFile(fName); Close();
    }
}
if(1*WSH.Arguments.Named.Item(&quot;FORMATRECOMMENDATIONS&quot;) &amp;&amp; newText){
    var lines = newText.split(&quot;\r\n&quot;), recommended_audio_format = &quot;&quot;, recommended_video_format = &quot;&quot;, recommended_format = &quot;&quot;;
    var audio_regexp = &quot;&quot;, video_regexp = &quot;&quot;, regexp = &quot;&quot;, page_specific = {
        &quot;AM_Live,interviews_on_vkvideo&quot;:[/:\/\/vkvideo\.ru\/video-(?:21732035|20648295|35758136)_/,
                                        /(^hls\S+_2\D\S*)\s/, /(^hls\S+)\s.+(?:25|30) \|/],
        &quot;vkvideo.ru:Mobile-Review.com&quot;: [/&lt;vkvideo\.ru:Mobile-Review\.com&gt;/, /(^hls\S+_2\D\S*)\s/, /(^hls\S+)\s.+1920x1080\s+25 \|/],
        &quot;rutube.ru:Константин Кулаков&quot;: [/&lt;rutube\.ru:Константин Кулаков&gt;/, /(^default-\S+)\s/]
    }
    for(lineIndex in lines){
        line = lines[lineIndex];
        if(lineIndex&lt;=1)for(var i in page_specific)if(page_specific[i][0].test(line))
            if(page_specific[i].length==3){audio_regexp = page_specific[i][1]; video_regexp = page_specific[i][2]; break}
            else {regexp = page_specific[i][1]; break}
        if(regexp &amp;&amp; regexp.test(line))recommended_format = RegExp.$1;
        else if(!audio_regexp &amp;&amp; !video_regexp &amp;&amp; /(^\S+)\s+mp4\s+1920x1080\s+25\D.*m3u8\s+\|\s+(?:unknown\s+unknown|avc1[.\d]+\s+mp4a[.\d]+)(?:\s|$)/.test(line))recommended_format = RegExp.$1;
        if(/audio only/.test(line)){
            if(audio_regexp){if(audio_regexp.test(line))recommended_audio_format = RegExp.$1}
            else if(/(^hls\S+)\s/.test(line))recommended_audio_format = RegExp.$1;
            else if(!/^hls/.test(recommended_audio_format) &amp;&amp; /(^\S+)\s+m4a/.test(line))recommended_audio_format = RegExp.$1;
        } else if(/video only/.test(line)){
            if(video_regexp){if(video_regexp.test(line))recommended_video_format = RegExp.$1}
            else if(/(^hls\S+)\s/.test(line))recommended_video_format = RegExp.$1;
            else if(!/^hls/.test(recommended_video_format) &amp;&amp; /(^\S+)\s+mp4\s+1920x1080\s+.*avc1/.test(line))recommended_video_format = RegExp.$1;
        }
    }
    if(recommended_format)WSH.echo(recommended_format);
    else WSH.echo(recommended_audio_format &amp;&amp; recommended_video_format ? recommended_audio_format + &quot;+&quot; + recommended_video_format : &quot;&quot;);
}

function getCodepage(oExec){
    while(!oExec.Status || !oExec.StdOut.AtEndOfStream){
        var new_codepage = /^[\s\S]*(?:REG_SZ|:)\s+(\S+)\s*$/.test(oExec.StdOut.ReadAll()) ? RegExp.$1 : &quot;&quot;;
    }
    return new_codepage;
}

function getCodepageName(oExec){
    var commandHead = &#039;reg.exe query &quot;HKCR\\MIME\\Database\\Codepage\\&#039;, codepage, WebCharset;
    oExec = WshShell.Exec(commandHead + (codepage = getCodepage(oExec)) + &#039;&quot; -v BodyCharset&#039;); var tempCodepageName = getCodepage(oExec);
    oExec = WshShell.Exec(commandHead + codepage + &#039;&quot; -v WebCharset&#039;); return (WebCharset = getCodepage(oExec)) ? WebCharset : tempCodepageName;
}
function DosToWin(dosString){
    var result;
    if(!CodePagesTestsDone){
        var oExec = WshShell.Exec(&#039;cmd.exe /c chcp&#039;);   var DOS_codepage = getCodepageName(oExec);
        oExec = WshShell.Exec(&#039;reg.exe query &quot;HKLM\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage&quot; -v ACP&#039;);    var Windows_codepage = getCodepageName(oExec);
        if(DOS_codepage != Windows_codepage)CodePages = [DOS_codepage, Windows_codepage];
        CodePagesTestsDone = true;
    }
    if(!CodePages.length)return dosString;
    with(str){
        Open();
        Charset = CodePages[1];
        WriteText(dosString);
        Position = 0;
        Charset = CodePages[0];
        result = ReadText();
        Close();
    }
    return result;
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (kvk-2019)]]></author>
			<pubDate>Mon, 03 Aug 2026 07:50:27 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18616&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: ЭТО КОТ?]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18600&amp;action=new</link>
			<description><![CDATA[<div class="codebox"><pre><code>SET K1=ЭТО ЗДЕСЬ
SET K3=ЭТО ЗДЕСЬ
SET K2=ЭТО 12/86
SET K1=НАУКА И ЖИЗНЬ
SET K5=ЭТО 12/86
SET K4=ЭТО 12/87
SET K2=РЕАКЦИЯ ЧИТАТЕЛЕЙ
SET K7=ЭТО ЗДЕСЬ
SET K6=ЭТО СОВЕТЫ 16 И 17
SET K3=КНИГА 128 СОВЕТОВ
SET K15=ЭТО ЗДЕСЬ
SET K14=ЭТО ТОМ 1 ГЛАВА 3
SET K7=МОИ ЗАМЕТКИ
SET K31=ЭТО ЗДЕСЬ
SET K30=ЭТО НАЕЗД НА ИНФОЦЫГАН
SET K15=НА ФОРУМЕ СТАРОГО ДОСА</code></pre></div><p>Что это такое? Очевидно, это кусок командного скрипта DOS/WIN. А зачем? Затем, что это БАЗА ДАНЫХ! Для той самой программы ЭТО КОТ, ссылки на которую перечислены. А это зачем? Затем, что мне показалось удобным вести по ходу дела записи о каких-то сиюминутных делах. Нет, конечно, ранее я предполагал, что на основе этой программки можно сделать более удобным форумное общение. Мол, не обмениваться случайными репликами, а высказывать свои тезисы более структурированно. Например, не &quot;топ 10 лучших игр для меня&quot;, а &quot;какие игры мне вспомнились сейчас и почему?&quot;.</p><p>Однако, с форумной версией ничего не получилось. Слишком высок оказался порог вхождения в игру. Ввести методу исподволь тоже оказалось сложным. Современные Сетевые технологии далеко переросли простые потребности обмена информацией. Я перенес эту игрушку в HTML (см. K62 ниже - <a href="https://gudleifr.mybb.ru/pages/kot">https://gudleifr.mybb.ru/pages/kot</a> ) и засунул на технологический форум. Но центр тяжести моментальна переключился с базы данных на эмуляцию консоли (с чем столкнулись уже первые первые современные переписчики BASIC-программы - K126 - <a href="https://gudleifr.forum2x2.ru/t18-topic#390">https://gudleifr.forum2x2.ru/t18-topic#390</a>) (<span class="postimg"><img src="http://gudleifr.byethost8.com/rkn.gif" alt="http://gudleifr.byethost8.com/rkn.gif" /></span> - форумная площадка попала под роскомнадзор). Но хуже того, задача автоматизации передачи результатов запуска программы обратно на форум простыми средствами не решается.</p><p><span class="postimg"><img src="https://gudleifr.byethost8.com/etokot.jpg" alt="https://gudleifr.byethost8.com/etokot.jpg" /></span></p><p>Так что, если удобная консоль - это DOS-овская, а передачу данных удобнее всего копипастить, то зачем изобретать велосипед? Хотите КОТА? Создайте в notepad файл etokot.bat:</p><div class="codebox"><pre><code>@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
&gt;&gt;ETOKOT.TXT ECHO.

REM СЛЕДУЮЩИЕ ТРИ СТРОЧКИ ЗАМЕНИТЬ ПОСЛЕ ПЕРВОГО ЗАПУСКА
REM НА ТЕКСТ ETOKOT.TXT. В ДАЛЬНЕЙШЕМ ДОБАВЛЯТЬ И ЧИСТИТЬ

SET K1=ЭТО %~1
IF &quot;%~1&quot;==&quot;&quot; SET K1=ЭТО ЧТО-ТО НЕПОНЯТНОЕ
&gt;&gt;ETOKOT.TXT ECHO SET K1=%K1%

REM КОНЕЦ БАЗЫ ДАННЫХ

:P10
SET I=1
:P20
SET /P O=!K%I%!? 
SET /A N=I*2
IF DEFINED K%N% GOTO P70
IF /I &quot;%O%&quot; NEQ &quot;Д&quot; GOTO P50
ECHO УРРА-А!
SET /P O=ХВАТИТ? 
IF /I &quot;%O%&quot;==&quot;Д&quot; EXIT /B
GOTO P10
:P50
SET /A N+=1
SET K%N%=!K%I%!
&gt;&gt;ETOKOT.TXT ECHO SET K%N%=!K%N%!
SET /P O=А ЧТО ЭТО? 
SET /A N=I*2
SET K%N%=ЭТО %O%
&gt;&gt;ETOKOT.TXT ECHO SET K%N%=!K%N%!
SET /P O=ЧЕМ ОТЛИЧАЕТСЯ? 
SET K%I%=%O%
&gt;&gt;ETOKOT.TXT ECHO SET K%I%=!K%I%!
GOTO P10
:P70
SET /A I*=2
IF /I &quot;%O%&quot; NEQ &quot;Д&quot; SET /A I+=1
GOTO P20</code></pre></div><p>Можно заметить, что метки примерно соответствуют номерам BASIC-строкам. Хитрости запуска сводятся к тому, что лучше заранее решить, что будем классифицировать. Лучше, если это будут однотипные &quot;предметы одного размера&quot;. Хорошо, весело например, протекает игра в оценку присутствующих студентов и отсутствующих преподов.</p><p>Если запустить скрипт без параметров, игра начинается так:</p><div class="codebox"><pre><code>&gt;etokot.bat
ЭТО ЧТО-ТО НЕПОНЯТНОЕ?</code></pre></div><p>с параметром (кавычки нужны если есть пробелы):</p><div class="codebox"><pre><code>&gt;etokot.bat &quot;ФИЛЬМ О СТЕЛС В ГРУЗОВОМ ОТСЕКЕ&quot;
ЭТО ФИЛЬМ О СТЕЛС В ГРУЗОВОМ ОТСЕКЕ?</code></pre></div><p>Дальше - все как раньше:<br /><span class="postimg"><img src="https://gudleifr.byethost8.com/c861.jpg" alt="https://gudleifr.byethost8.com/c861.jpg" /></span></p><p>После УРРА-А! можно выйти:</p><div class="codebox"><pre><code>ЭТО 12/87? Д
УРРА-А
ХВАТИТ? Д</code></pre></div><p>Результат накапливается по ходу разговора в ETOKOT.TXT - см. &quot;код&quot; в начале поста. По окончании первого диалога этим кодом нужно заменить ввод K1:</p><div class="codebox"><pre><code>@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
&gt;&gt;ETOKOT.TXT ECHO.

SET K1=ЭТО ЗДЕСЬ
SET K3=ЭТО ЗДЕСЬ
SET K2=ЭТО 12/86
SET K1=НАУКА И ЖИЗНЬ
SET K5=ЭТО 12/86
SET K4=ЭТО 12/87
SET K2=РЕАКЦИЯ ЧИТАТЕЛЕЙ
SET K7=ЭТО ЗДЕСЬ
SET K6=ЭТО СОВЕТЫ 16 И 17
SET K3=КНИГА 128 СОВЕТОВ
SET K15=ЭТО ЗДЕСЬ
SET K14=ЭТО ТОМ 1 ГЛАВА 3
SET K7=МОИ ЗАМЕТКИ
SET K31=ЭТО ЗДЕСЬ
SET K30=ЭТО НАЕЗД НА ИНФОЦЫГАН
SET K15=НА ФОРУМЕ СТАРОГО ДОСА

REM КОНЕЦ БАЗЫ ДАННЫХ
...</code></pre></div><p>После этого можно продолжить:</p><div class="codebox"><pre><code>&gt;etokot.bat
НАУКА И ЖИЗНЬ? Н
КНИГА 128 СОВЕТОВ? Н
МОИ ЗАМЕТКИ? Д
ЭТО ТОМ 1 ГЛАВА 3? Н
А ЧТО ЭТО? ТОМ 2 ГЛАВА 2
ЧЕМ ОТЛИЧАЕТСЯ? ПРИМЕР BASIC КОНСОЛИ
НАУКА И ЖИЗНЬ? Н
КНИГА 128 СОВЕТОВ? Н
МОИ ЗАМЕТКИ? Д
ПРИМЕР BASIC КОНСОЛИ? Д
...</code></pre></div><p>При этом в ETOKOT.TXT допишется (то, что я забыл при первом сеансе):</p><div class="codebox"><pre><code>SET K29=ЭТО ТОМ 1 ГЛАВА 3
SET K28=ЭТО ТОМ 2 ГЛАВА 2
SET K14=ПРИМЕР BASIC КОНСОЛИ
SET K63=ЭТО ЗДЕСЬ
SET K62=ЭТО HTML ПРОГРАММА
SET K31=НА НОВОМ ФОРУМЕ
SET K127=ЭТО ЗДЕСЬ
SET K126=ЭТО ЗАДАЧКА 1
SET K63=В ПРОЧИХ СТАТЬЯХ</code></pre></div><p>Т.к. все новое просто дописывается в конец ETOKOT.TXT, то можно копипастить в/из него все, что угодно. Например, черновик этого поста я пишу прямо в нем. Нужно только не забывать сохраняться перед перезапуском etokot.bat.</p><p>После накопления базы в ETOKOT.TXT ее можно привести в нужный вид. Например, я написал kotogluk.bat для преобразования базы в заголовки ГЛЮКВЫ:</p><div class="codebox"><pre><code>@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

REM СЮДА ВСТАВИТЬ ETOKOT.TXT

SET K1=ЭТО ЗДЕСЬ
... не буду повторять
SET K63=В ПРОЧИХ СТАТЬЯХ

REM КОНЕЦ БАЗЫ ДАННЫХ

SET I=1
SET O1=\
:POWTOR
SET /A N=I*2
IF DEFINED K%N% GOTO WPERED
ECHO !O%I%!!K%I%:~4!
GOTO WPRAWO
:WPERED
SET O%N%=!O%I%!!K%I%!\
SET /A N+=1
SET O%N%=!O%I%!
SET /A I=N-1
GOTO POWTOR
:WPRAWO
SET /A N=&quot;I&gt;&gt;1&lt;&lt;1&quot;
IF %N% NEQ %I% GOTO NET
SET /A I+=1
GOTO POWTOR
:NET
SET /A I/=2
IF %I% NEQ 0 GOTO WPRAWO</code></pre></div><p>Получилось гораздо короче (хотя, часть информации о порядке поиска была потяряна):</p><div class="codebox"><pre><code>\НАУКА И ЖИЗНЬ\РЕАКЦИЯ ЧИТАТЕЛЕЙ\12/87
\НАУКА И ЖИЗНЬ\12/86
\КНИГА 128 СОВЕТОВ\СОВЕТЫ 16 И 17
\МОИ ЗАМЕТКИ\ПРИМЕР BASIC КОНСОЛИ\ТОМ 2 ГЛАВА 2
\МОИ ЗАМЕТКИ\ТОМ 1 ГЛАВА 3
\НА ФОРУМЕ СТАРОГО ДОСА\НАЕЗД НА ИНФОЦЫГАН
\НА НОВОМ ФОРУМЕ\HTML ПРОГРАММА
\В ПРОЧИХ СТАТЬЯХ\ЗАДАЧКА 1
\ЗДЕСЬ</code></pre></div><p>По окончании работы нужно ETOKKOT.TXT (и/или etokot.bat c базой) сохранить в какой-нибудь директории.</p><p>МОРАЛЬ: При программировании DOS-скриптов можно хранить код, данные и комментарии в одном и том же текстовом файле. И копипастить в другие по необходимости. И это зачастую удобнее, чем организовывать правильный файловый обмен и разрабатывать интерфейсы.</p><p>ВОПРОС: До какого места Вы дочитали?</p>]]></description>
			<author><![CDATA[null@example.com (gudleifr)]]></author>
			<pubDate>Fri, 12 Jun 2026 10:59:48 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18600&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: посимвольный перебор строки (сравнение скорости двух методов)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18587&amp;action=new</link>
			<description><![CDATA[<p>Посимвольный перебор строки можно сделать двумя способами:<br />1. Завести индекс, брать символ в позиции индекса, инкремировать, проверять на достижение конца строки, goto.<br />2. Перебирать индекс в for, брать символ в позиции индекса, проверять на достижение конца строки, goto.</p><p>Сравним оба варианта на скорость работы:</p><div class="codebox"><pre><code>@echo off
setlocal enabledelayedexpansion

:: Формируем строку из 8000 символов
set &quot;str=&quot;
for /l %%i in (1,1,8000) do set &quot;str=!str!A&quot;

:: ===== МЕТОД 1: Доступ по индексу =====
echo Method1:

:: Замер времени начала
call :gettick
set start=%errorlevel%

set idx=0
:loop1
    set &quot;ch=!str:~%idx%,1!&quot;
    if not defined ch goto end1
    rem Тут работа с символом в ch...
    set /a idx+=1
    goto loop1
:end1

:: Замер времени окончания
call :gettick
set end=%errorlevel%

set /a tm=(%end%-%start%)*10
if %tm% lss 0 set /a tm+=24*3600000

echo   Time: %tm% ms
echo.

:: ===== МЕТОД 2: Доступ через цикл for =====
echo Method2:

call :gettick
set start=%errorlevel%

:: 8192 - максимально возможная длина строки в CMD
for /l %%i in (0,1,8192) do (
    set &quot;ch=!str:~%%i,1!&quot;
    if not defined ch goto end2
    rem Тут работа с символом в ch...
)
:end2

call :gettick
set end=%errorlevel%

set /a tm=(%end%-%start%)*10
if %tm% lss 0 set /a tm+=24*3600000

echo   Time: %tm% ms
echo.

exit /b

:gettick
:: Количество сотых долей секунды, прошедших с начала дня
setlocal
set t=%time: =0%
set /a tick=1%t:~9,2%-100+(1%t:~6,2%-100)*100+(1%t:~3,2%-100)*6000+(1%t:~0,2%-100)*360000
endlocal &amp; exit /b %tick%</code></pre></div><p>Итог на моем компе:</p><div class="codebox"><pre><code>Method1:
  Time: 6240 ms

Method2:
  Time: 310 ms</code></pre></div><p>Метод с for быстрее аж в 20 раз!</p><p><strong>Вывод:</strong> для посимвольного перебора строки выгодно использовать цикл for. Так как заранее не знаем длину строки, то верхнюю границу берем по максимуму, а из цикла выходим по if и goto.</p><p>P.S. проверка на пустоту через</p><div class="codebox"><pre><code>if not defined ch goto end1</code></pre></div><p>немного быстрее проверки через</p><div class="codebox"><pre><code>if &quot;!ch!&quot;==&quot;&quot; goto end1</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Arigato)]]></author>
			<pubDate>Sat, 02 May 2026 13:50:42 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18587&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Автоматическое создание Proxy-файлов видео для Vegas]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18536&amp;action=new</link>
			<description><![CDATA[<p><strong>Автоматическое создание Proxy-файлов видео с камеры DJI Osmo Action 5 Pro для Vegas</strong></p><p>Камера <strong>DJI Osmo Action 5 Pro</strong> кроме оригинального видео также создает файл с расширением <strong>.LRF</strong>, содержащий видео с меньшем разрешением (1280*720 30fps).</p><p>При работе с роликами в высоком разрешении в видеоредакторе Vegas может потребоваться создание прокси-файлов, то есть копий оригинального ролика с меньшем разрешением, чтобы не тормозил предпросмотр во время монтажа в самой программе. Vegas умеет создавать прокси, но это долго и муторно. Куда лучше использовать в качестве прокси уже имеющиеся файлы .LRF.</p><p><strong>Пошаговая инструкция, как преобразовать .LRF в Proxy для Vegas:</strong><br /></p><ol class="decimal"><li><p>Скачать утилиту <strong>ffmpeg</strong> для конвертации форматов - <a href="https://ffmpeg.org/download.html">https://ffmpeg.org/download.html</a></p></li><li><p>Прописать путь к файлу <strong>ffmpeg.exe</strong> в переменные среды <strong>PATH</strong>: <em>Откройте Параметры Windows (Win + I); Система → О программе → Дополнительные параметры системы; во вкладке &quot;Дополнительно&quot; нажмите &quot;Переменные среды...&quot;; в переменную Path добавить путь к папке с ffmpeg.</em></p></li><li><p>При копировании видео с камеры, скопировать в том числе и файлы с расширением <strong>.LRF</strong></p></li><li><p>В папку, куда скопированы видео-файлы с камеры, скопировать файл <strong>Proxy.cmd</strong> (см. вложение, не забудьте достать его из zip-архива).</p></li><li><p>Запустить <strong>Proxy.cmd</strong>, дождаться завершения процесса (должны исчезнуть все черные окна). По итогу у вас появятся файлы с расширением <strong>.MP4.sfvp0</strong>, это и есть прокси для Vegas.</p></li><li><p>Дальше просто работаете в Vegas, она автоматически подтянет данные прокси. Чтобы в окне предпросмотра использовались прокси-файлы (а не оригинальные), выставите режим предпросмотра <strong>Preview (Full)</strong> или <strong>Half</strong>, если у вас все равно тормозит воспроизведение.</p></li></ol><p>Шаги 1 и 2 проделываются один раз, в последующем они не требуются.</p><p><strong>Важные замечания:</strong><br /></p><ol class="decimal"><li><p>Во время создания прокси-файлов появится куча черных окошек (на каждый файл по одному окошку) и комп прилично нагрузится (как ЦП, так и видеокарта). Скорость процесса зависит от мощности вашего железа и количества файлов. Например, у меня порядка 100 файлов обрабатывались около 1 минуты 20 секунд.</p></li><li><p>Видеокарта <strong>NVidia</strong>! Для других карт надо поменять параметр <strong>GPU_ACCEL</strong> на <strong>amf</strong> для AMD и <strong>qsv</strong> для Intel. Но в этих режимах не тестировалось. Можно этому параметру присвоить пустое значение (тогда весь процесс пойдет через ЦП).</p></li><li><p>Этот скрипт также делает прокси и для видео с дрона <strong>Fimi X8 Mini</strong> (<em>приятный бонус</em>).</p></li><li><p>Тестировалось в <strong>VEGAS Pro 21.0</strong>.</p></li><li><p>В некоторых случаях возможна небольшая рассинхронизация прокси с оригиналом, особенно это касается таких FPS, как 48, 50, 100.</p></li><li><p>Прокси с гиперлапс-видео Vegas не принимает.</p></li><li><p>С таймлапс-видео прокси вообще отсутствует (можно сделать средствами самого Vegas).</p></li></ol><div class="codebox"><pre><code>:: ==============================================
:: Батник создания Proxy-файлов для VEGAS Pro 21.0 (и других версий)
:: Проверено по данным с камеры DJI Osmo Action 5 Pro и дрона Fimi X8 Mini
:: Для работы нужно установить ютилиту FFmpeg - https://ffmpeg.org/download.html
:: (c) Arigato Software, 2025
:: ==============================================

@echo off
setlocal enabledelayedexpansion

:: ==============================================
:: Конфигурация
:: ==============================================
:: Расширение прокси-файлов
set PROXY_EXT=MP4.sfvp0
:: Битрейт прокси
set BITRATE=12M
:: Ширина прокси
set WIDTH=1280
:: Высота прокси
set HEIGHT=720
:: GPU-ускорение (NVIDIA=cuda, AMD=amf, INTEL=qsv, CPU=пусто)
set GPU_ACCEL=cuda
:: Включение аудио в прокси (1=вкл, 0=выкл, для Vegas выкл!)
set INCLUDE_AUDIO=0

:: ==============================================
:: Обработка файлов *.LRV и *.LRF
:: ==============================================
echo [INFO] Create proxy files

:: Применяем параметры
if not &quot;!GPU_ACCEL!&quot;==&quot;&quot; set &quot;GPU_ACCEL=-hwaccel !GPU_ACCEL!&quot;
if !INCLUDE_AUDIO! equ 1 (
	set &quot;INCLUDE_AUDIO=-c:a aac -b:a 128k&quot;
) else (
	set &quot;INCLUDE_AUDIO=-an&quot;
)

:: Перебор всех .LRV и .LRF-файлов
for %%i in (*.LRV *.LRF) do (
	set &quot;source_filename=%%~ni.MP4&quot;
	set &quot;proxy_filename=%%~ni.%PROXY_EXT%&quot;
	echo !source_filename!
	
	:: Определяем FPS оригинала
	call :get_fps &quot;!source_filename!&quot; source_fps
	echo FPS: !source_fps!
	
	:: Получаем количество кадров
	call :frames &quot;!source_filename!&quot; frames
	echo Frames: !frames!
	
	:: Определяем поворот
	call :rotation &quot;%%i&quot; rotation_degrees
	if !rotation_degrees! neq 0 (
		echo Rotation: !rotation_degrees!
	)
	
	:: Выбираем фильтр поворота
	set &quot;vf_rotate=&quot;
	if !rotation_degrees! equ 90 set &quot;vf_rotate=transpose=1,&quot;
	if !rotation_degrees! equ 180 set &quot;vf_rotate=transpose=1,transpose=1,&quot;
	if !rotation_degrees! equ 270 set &quot;vf_rotate=transpose=2,&quot;
	
	:: Запускаем кодирование
	start &quot;!source_filename!&quot; ffmpeg !GPU_ACCEL! -i &quot;%%i&quot; -y -c:v mpeg2video ^
		-b:v %BITRATE% ^
		!INCLUDE_AUDIO! ^
		-vf &quot;!vf_rotate!scale=%WIDTH%:%HEIGHT%:force_original_aspect_ratio=decrease,setsar=1,fps=!source_fps!&quot; ^
		-f mp4 -r !source_fps! ^
		-movflags faststart -timecode &quot;00:00:00:00&quot; ^
		-fps_mode cfr -frames:v !frames! ^
		&quot;!proxy_filename!&quot;
)

:: ==============================================
:: Завершение работы
:: ==============================================
echo [SUCCESS] OK
rem pause
exit /b 0

:: ==============================================
:: Функция определения количества кадров
:: %1 - файл, %2 - выходная переменная
:: ==============================================
:frames
setlocal
set &quot;frames=0&quot;
for /f %%f in (
	&#039;ffprobe -v error -select_streams v:0 -show_entries stream^=nb_frames -of default^=nokey^=1:noprint_wrappers^=1 &quot;%~1&quot; 2^&gt;^&amp;1&#039;
) do set &quot;frames=%%f&quot;
endlocal &amp; set &quot;%~2=%frames%&quot;
exit /b 0

:: ==============================================
:: Функция определения поворота видео
:: %1 - файл, %2 - выходная переменная
:: ==============================================
:rotation
setlocal
set &quot;rot=0&quot;
for /f &quot;tokens=2 delims==&quot; %%r in (
	&#039;ffprobe -v error -select_streams v:0 -show_entries stream_side_data^=rotation -of default^=nw^=1 &quot;%~1&quot;&#039;
) do set &quot;rot=%%r&quot;

:: Нормализация отрицательных значений
if &quot;!rot!&quot;==&quot;-90&quot; set &quot;rot=270&quot;
if &quot;!rot!&quot;==&quot;-180&quot; set &quot;rot=180&quot;
if &quot;!rot!&quot;==&quot;-270&quot; set &quot;rot=90&quot;
endlocal &amp; set &quot;%~2=%rot%&quot;
exit /b 0

:: ==============================================
:: Функция определения частоты кадров видео
:: %1 - файл, %2 - выходная переменная
:: Возвращает fps в формате &quot;60000/1001&quot; (59.94) или &quot;30/1&quot; (30.0)
:: ==============================================
:get_fps
setlocal
set &quot;fps_value=0/0&quot;
for /f &quot;tokens=2 delims==&quot; %%f in (
    &#039;ffprobe -v error -select_streams v:0 -show_entries stream^=r_frame_rate -of default^=nw^=1 &quot;%~1&quot;&#039;
) do (
    set &quot;fps_value=%%f&quot;
    :: Удаляем возможные кавычки
    set &quot;fps_value=!fps_value:&quot;=!&quot;
)
endlocal &amp; set &quot;%~2=%fps_value%&quot;
exit /b 0</code></pre></div><p>P.S. Можно модифицировать скрипт для других видеоредакторов.</p>]]></description>
			<author><![CDATA[null@example.com (Arigato)]]></author>
			<pubDate>Fri, 19 Dec 2025 21:58:39 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18536&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: звуки (3 разных + бонус: сигнал SOS)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18487&amp;action=new</link>
			<description><![CDATA[<p>Два примера, как вывести звук из батника:</p><div class="codebox"><pre><code>@ echo off
setlocal enabledelayedexpansion

pause
echo Звуковой сигнал №1
call :beep1

pause
echo Звуковой сигнал №2
call :beep2

exit /b

:: Звуковой сигнал через символ с кодом 7 (Alt + 07)
:beep1
setlocal
0&lt;nul set /p =[BEL]
endlocal &amp; exit /b

:: Звуковой сигнал через choice
:beep2
echo 0y | choice /c y /n&gt;nul
exit /b</code></pre></div><p><strong>[BEL]</strong> - это непечатный символ с кодом 7. В форум его вставить нельзя, так что работающий пример качайте из вложения.</p><p>Подпрограмма <strong>beep1</strong> выводит звук через символ с кодом 7.<br />Подпрограмма <strong>beep2</strong> выводит звук через команду choice.</p><p>Не факт что везде будет работать, не проверял, но у меня оба метода работают и звуки разные.</p><p><strong>Сигнал SOS</strong></p><p>А вот и пример реализации сигнала SOS через звуки и мигание экраном:</p><div class="codebox"><pre><code>@ echo off
setlocal enabledelayedexpansion

cls
title Сигнал SOS

:sos
call :M_S
call :M_O
call :M_S
call :pause 2
echo.
goto sos

exit /b

:: O: ---
:M_O
call :dash
call :dash
call :dash
exit /b

:: S: ...
:M_S
call :dot
call :dot
call :dot
exit /b

:: Точка (Морзе)
:dot
setlocal
0&lt;nul set /p =.
color f0
call :beep2
color 07
endlocal &amp; exit /b

:: Тире (Морзе)
:dash
setlocal
0&lt;nul set /p =-
color f0
call :beep2
call :pause
color 07
endlocal &amp; exit /b

:: Звуковой сигнал через choice
:beep2
echo 01 | choice /c 1 /n&gt;nul
exit /b

:: Задержка в сек (0 - короткая задержка)
:pause
setlocal
set t=%1
if &quot;%t%&quot;==&quot;&quot; set t=0
timeout /t %t% &gt;nul
endlocal &amp; exit /b
</code></pre></div><p>Так как звук подается вызовом подпрограммы beep2, которая работает через choice, то и непечатных символов тут нет. Можно копировать код прямо с форума.</p>]]></description>
			<author><![CDATA[null@example.com (Arigato)]]></author>
			<pubDate>Tue, 02 Sep 2025 21:04:26 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18487&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Многозадачность]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18486&amp;action=new</link>
			<description><![CDATA[<p>Для реализации некоторого параллельного программирования в CMD можно использовать такую команду:</p><div class="codebox"><pre><code>start /b имя.cmd</code></pre></div><p>Параметр <strong>/b</strong> позволяет запустить скрипт имя.cmd в том же консольном окне, при этом основная программа продолжает выполнение, а имя.cmd работает совместно, разделяя с ней потоки ввода-вывода.</p><p>Вот такой пример. Батник <strong>main.cmd</strong>:<br /></p><div class="codebox"><pre><code>@echo off
setlocal enabledelayedexpansion

cls
set test_var=Hello, second
start /b second.cmd

FOR /L %%i IN (0,1,10) DO (
	echo Thread_1: %%i
	timeout /t 1 &gt;nul
)

set test_var=Goodby, second
echo Thread_1 ending</code></pre></div><p>Батник <strong>second.cmd</strong>:<br /></p><div class="codebox"><pre><code>@echo off

echo %test_var%

FOR /L %%i IN (0,1,10) DO (
	echo Thread_2: %%i
	timeout /t 2 &gt;nul
)

echo Thread_2 ending
echo %test_var%</code></pre></div><p>Виден параллельный вывод в одну и туже консоль. При этом имеется возможность &quot;передать&quot; все данные из основной программы в параллельный поток. В примере это переменная test_var. Однако в second.cmd создается лишь ее копия, то есть не получится менять значение переменной одного потока из другого.</p><p>Если все же надо наладить взаимодействие двух потоков, то придется использовать общий файл.</p><p><strong>Где можно использовать на практике?</strong></p><p>Например, команда <strong>choice</strong> не просто считывает нажатую клавишу, но и останавливает выполнение до того, пока пользователь не нажмет клавишу. Если нам надо отслеживать нажатые клавиши, при этом не тормозить основной поток, то обработку клавиатуры можно вынести в отдельный поток. Например:<br /></p><div class="codebox"><pre><code>@echo off
:loop
choice /c YN /n /cs
echo %errorlevel% &gt; input.txt
goto loop
</code></pre></div><p>Нажатая клавиша окажется в файле input.txt (точнее ее порядковый номер в списке). От туда основной поток в нужный момент может произвести чтение, не останавливая своей работы на ожидание нажатия клавиши.</p><p>Это лишь один пример, можно придумать и другие способы применения подобной многопоточности.</p>]]></description>
			<author><![CDATA[null@example.com (Arigato)]]></author>
			<pubDate>Tue, 02 Sep 2025 17:19:28 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18486&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Управляющие последовательности ANSI/ECMA-48]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18484&amp;action=new</link>
			<description><![CDATA[<p>Дополним тему <a href="https://forum.script-coding.com/viewtopic.php?id=7944">CMD/BAT: Вывод разноцветного текста</a>, точнее предложим совершенно новое и куда более продвинутое решение.</p><p>О чем идет речь, подробнее читайте тут - <a href="https://ru.wikipedia.org/wiki/%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D1%8E%D1%89%D0%B8%D0%B5_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_ANSI">Управляющие последовательности ANSI</a></p><p>Данная методика работает начиная с Windows 10.</p><p><span class="postimg"><img src="https://i.ibb.co/MkKwQgnL/2.png" alt="https://i.ibb.co/MkKwQgnL/2.png" /></span></p><p>Для управления выводом текста в консоль используются специальные ESC-коды. Выглядят они так:</p><div class="codebox"><pre><code>ESC[&lt;параметры&gt;&lt;буква-команда&gt;</code></pre></div><p>ESC[ — признак начала управляющей последовательности. Непечатный символ с кодом 27 (U+001B). Набирается посредством Alt+27 или Alt+027, на экране выглядит как вопросик в квадрате или иначе, в зависимости от редактора.<br />&lt;параметры&gt; — цифры (иногда с ; ), указывают режим или количество.<br />&lt;буква-команда&gt; — финализирующий символ, указывающий какое именно действие.</p><p>Так как символ ESC непечатный, то не всегда удастся вставить код в сообщение, примеры надо качать из вложений.</p><p>Команда m задает цвет текста и фона (цвет задается или из палитры 16, или из палитры 256, или по RGB), различные начертания шрифта (подчеркнутый, жирный).</p><p><strong>Цвета из палитры 16</strong></p><p><a href="https://ibb.co/fdwDRVqf"><span class="postimg"><img src="https://i.ibb.co/yFj4Tmdt/1.png" alt="https://i.ibb.co/yFj4Tmdt/1.png" /></span></a></p><p><strong>Цвета из палитры 256</strong></p><p>ESC[38;5;&lt;n&gt;m&nbsp; &nbsp;→ цвет текста<br />ESC[48;5;&lt;n&gt;m&nbsp; &nbsp;→ цвет фона</p><p>где &lt;n&gt; от 0 до 255.<br />0–7: базовые цвета<br />8–15: яркие<br />16–231: 6×6×6 RGB-куб<br />232–255: градации серого</p><p><strong>Полноцветный (TrueColor, 24-бит)</strong></p><p>ESC[38;2;R;G;Bm&nbsp; &nbsp;→ текст (R,G,B = 0–255)<br />ESC[48;2;R;G;Bm&nbsp; &nbsp;→ фон</p><p>Пример:<br /></p><div class="codebox"><pre><code>echo [38;2;255;128;0mОранжевый текст[0m</code></pre></div><p><strong>Основные атрибуты</strong></p><p>ESC[0m&nbsp; &nbsp;→ сброс атрибутов<br />ESC[1m&nbsp; &nbsp;→ жирный / яркий цвет<br />ESC[2m&nbsp; &nbsp;→ тусклый<br />ESC[3m&nbsp; &nbsp;→ курсив (обычно игнорируется)<br />ESC[4m&nbsp; &nbsp;→ подчёркивание<br />ESC[5m&nbsp; &nbsp;→ мигающий (обычно игнорируется)<br />ESC[7m&nbsp; &nbsp;→ инверсия<br />ESC[8m&nbsp; &nbsp;→ скрытый<br />ESC[9m&nbsp; &nbsp;→ зачёркнутый<br />ESC[22m&nbsp; → отмена жирного/тусклого<br />ESC[24m&nbsp; → отмена подчёркивания<br />ESC[27m&nbsp; → отмена инверсии<br />ESC[30–37m&nbsp; → цвет текста<br />ESC[40–47m&nbsp; → цвет фона<br />ESC[90–97m&nbsp; → яркие цвета текста<br />ESC[100–107m → яркие цвета фона<br />ESC[38;5;#m&nbsp; → текст 256-цвет<br />ESC[48;5;#m&nbsp; → фон 256-цвет<br />ESC[38;2;R;G;Bm → текст TrueColor (24-бит)<br />ESC[48;2;R;G;Bm → фон TrueColor (24-бит)</p><p>Работает далеко не все...</p><p><strong>Комбинирование</strong></p><p>Можно комбинировать через ;. Например:</p><div class="codebox"><pre><code>[4;31mподчёркнутый красный[0m
[7;33mжёлтый инверсный[0m
</code></pre></div><p><strong>Сброс всех атрибутов</strong></p><p>ESC[0m&nbsp; &nbsp;→ сброс атрибутов</p><p><strong>Очистка экрана</strong></p><p>ESC[J&nbsp; &nbsp; → очистка экрана (по умолчанию от курсора до конца)<br />ESC[0J&nbsp; &nbsp;→ от курсора до конца экрана<br />ESC[1J&nbsp; &nbsp;→ от начала экрана до курсора<br />ESC[2J&nbsp; &nbsp;→ весь экран<br />ESC[3J&nbsp; &nbsp;→ весь экран + буфер (если поддерживается)</p><p>ESC[K&nbsp; &nbsp; → очистка строки (по умолчанию от курсора до конца)<br />ESC[0K&nbsp; &nbsp;→ от курсора до конца строки<br />ESC[1K&nbsp; &nbsp;→ от начала строки до курсора<br />ESC[2K&nbsp; &nbsp;→ вся строка</p><p><strong>Управление курсором</strong></p><p>ESC[#A&nbsp; &nbsp;→ вверх # строк<br />ESC[#B&nbsp; &nbsp;→ вниз # строк<br />ESC[#C&nbsp; &nbsp;→ вправо # колонок<br />ESC[#D&nbsp; &nbsp;→ влево # колонок<br />ESC[#E&nbsp; &nbsp;→ на начало строки, ниже на #<br />ESC[#F&nbsp; &nbsp;→ на начало строки, выше на #<br />ESC[#G&nbsp; &nbsp;→ в колонку #<br />ESC[H → курсор в левый верхний угол<br />ESC[#;#H → в строку;колонку (позиция курсора)<br />ESC[#;#f → то же самое (альтернативная форма)</p><p>ESC[s&nbsp; &nbsp; → сохранить позицию курсора<br />ESC[u&nbsp; &nbsp; → восстановить позицию курсора</p><p>ESC[?25l → скрыть курсор<br />ESC[?25h → показать курсор</p><p>ESC[6n&nbsp; &nbsp;→ выводит текущее положение курсора в формате ^[[n;mR, где n — строка, m — столбец. Ответ попадает в поток ввода. Пока непонятно, как его считать...</p><p><strong>Прокрутка</strong></p><p>ESC[#S&nbsp; &nbsp; → прокрутить экран вверх на #<br />ESC[#T&nbsp; &nbsp; → прокрутить экран вниз на #</p><p>Пример:</p><div class="codebox"><pre><code>@echo off
echo Очистка экрана: [2J
echo Красный текст: [31mHello[0m
echo Подчёркнутый: [4mText[0m
echo Инверсия: [7mInverted[0m
</code></pre></div><p>Более полная демка во вложении. Скрины демки:</p><p><a href="https://ibb.co/Vc2sYD8X"><span class="postimg"><img src="https://i.ibb.co/Vc2sYD8X/1.png" alt="https://i.ibb.co/Vc2sYD8X/1.png" /></span></a> <a href="https://ibb.co/TxG1N1fK"><span class="postimg"><img src="https://i.ibb.co/TxG1N1fK/3.png" alt="https://i.ibb.co/TxG1N1fK/3.png" /></span></a></p>]]></description>
			<author><![CDATA[null@example.com (Arigato)]]></author>
			<pubDate>Mon, 01 Sep 2025 19:05:58 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18484&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Корректно работает только при повторном запуске, баг?]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18455&amp;action=new</link>
			<description><![CDATA[<p>Почему такой код срабатывает только со второго раза?</p><p>Файл wat.cmd<br /></p><div class="codebox"><pre><code>@echo off
if not &quot;%1&quot;==&quot;&quot; (
	set attr=%~a1
	echo %attr%
)
</code></pre></div><p>:<br /></p><div class="quotebox"><blockquote><p>C:\#_\TEST&gt;wat.cmd wat.cmd<br />Режим вывода команд на экран (ECHO) отключен.</p><p>C:\#_\TEST&gt;wat.cmd wat.cmd<br />--a--------</p></blockquote></div><p>Но вот так работает с первого:<br /></p><div class="codebox"><pre><code>@echo off
if not &quot;%1&quot;==&quot;&quot; (
	echo %~a1
)
</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (DnsIs)]]></author>
			<pubDate>Mon, 02 Jun 2025 10:59:18 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18455&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Получить температуру процессора]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18451&amp;action=new</link>
			<description><![CDATA[<p>Батник выводит температуру процессора в градусах Цельсия с точностью до двух знаков после десятичной точки:</p><div class="codebox"><pre><code>@echo off
for /f &quot;skip=1 tokens=2 delims==&quot; %%A in (&#039;wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature /value&#039;) do (
   set Kel=%%~A
)
set /a Deg=Kel*10-27315
set CPU_Temp=%Deg:~0,-2%.%Deg:~-2%
echo CPU temperature: %CPU_Temp% C</code></pre></div><p>Батник надо запускать от администратора.</p>]]></description>
			<author><![CDATA[null@example.com (Arigato)]]></author>
			<pubDate>Thu, 22 May 2025 07:02:41 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18451&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Открыть файл 7z архив и удалить первые символы]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18408&amp;action=new</link>
			<description><![CDATA[<p>Добрый день, </p><p>Надо в командной строке coздать архив и в файле (архиве) потом изменить (удалить, добавить) первые символы.<br />Создаю Архив:<br /></p><div class="codebox"><pre><code>&quot;C:\Program Files\7-Zip\7z.exe&quot; a password.7z password.txt -pP@$$w0rd</code></pre></div><p>Пробовол удалить так первые 2 символа<br /></p><div class="codebox"><pre><code>
...
&lt;&quot;password.7z&quot; set /p sLine=&gt;nul
echo %sLine:~2%&gt;&quot;password.7z.not_7z_file&quot; 
more +1 &quot;password.7z&quot;&gt;&gt;&quot;password.7z.not_7z_file&quot;
...
</code></pre></div><p>Но файл полностью меняется и не работает потом, если удаляю (добавляю) вручную в Notepad++, то все работает.</p><p>Как это автоматизировать?</p><p>Заранее благодарю.</p><br /><div class="codebox"><pre><code>7z¼¯&#039; Ø4Ã       r       Õ&lt;ÜWüË„¤¯:@õNÖ.’3 	  $ñSã1?öáÝÒ«™¾r·HðÎ!!   
²T&amp;Y    p a s s w o r d . t x t    
 Ø‹TjÅÛ       </code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Димон)]]></author>
			<pubDate>Wed, 26 Mar 2025 08:00:40 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18408&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: запуск в скрытом режиме (SW_HIDE)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18335&amp;action=new</link>
			<description><![CDATA[<p>Start in SW_HIDE mode.<br />Есть какие-нибудь решения для данной задачи, господа форумчане-скриптописатели?</p><p>p.s. без использования сторонних средств.</p>]]></description>
			<author><![CDATA[null@example.com (АДМИНИСТРАТОР)]]></author>
			<pubDate>Mon, 02 Dec 2024 15:53:07 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18335&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Исключить расширение из имени файла]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18312&amp;action=new</link>
			<description><![CDATA[<div class="codebox"><pre><code>for f in &quot;$@&quot;; do
	/opt/homebrew/bin/ffmpeg -i &quot;$f&quot; -c:v libx265 -vtag hvc1 &quot;$f&quot;.mp4
	/bin/rm &quot;$f&quot;
done;</code></pre></div><p>Здравствуйте! Сценарий конвертирует видео и удаляет исходный файл. На выходе получаю файл с двойным расширением (<em>~mp4.mp4</em>). Как исключить расширение из названия исходного файла? На выходе файл должен иметь расширение .mp4, но на входе может быть .mov, .ts, .braw и т.д. Спасибо!</p>]]></description>
			<author><![CDATA[null@example.com (becauseim)]]></author>
			<pubDate>Fri, 11 Oct 2024 13:36:36 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18312&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Резервное копирование с версионностью.]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18212&amp;action=new</link>
			<description><![CDATA[<p>Доброго времени суток всем обитателям столь полезного ресурса, столкнулся с не простым вопросом (для меня, по крайней мере)</p><p>Суть такова:<br />Есть каталог на диске 1, есть каталог зеркала на диске 2, создаваемого с помощью BAT по средствам robocopy.<br />Хочу чтобы был дополнительный BAT который смотрит на каталог диска 1 сравнивая его с зеркалом каталога второго диска но поученный результат копировал в третий каталог своего рода версионность.<br />Суть идеи такова: с понедельника по пятницу работает пять BAT файлов для каждого дня недели, копирующих только те файлы которые были добавлены или изменены, в субботу же запускается основной BAT который очищает каталоги версий и делает новое зеркало.</p><p>Прежде чем создать топик я воспользовался поиском с запросом «robocopy» и «резервное копирование» просмотрев найденное нашел бизкое по теме, но не то что нужно.</p><p>На текущий момент мысли крутятся вокруг следующего кода:</p><div class="codebox"><pre><code>
@echo on
chcp 1251
setlocal enabledelayedexpansion

rem Параметры
set &quot;sourceDir=A:\$SUR&quot;
set &quot;targetDir=A:\$TARGT&quot;
set &quot;backupDir=A:\$CEL&quot;
set &quot;logFile=A:\$log\robocopy.log&quot;

rem Очистка лог-файла перед началом
echo. &gt; &quot;%logFile%&quot;

rem Запуск robocopy для сравнения каталогов и записи изменений в лог-файл
robocopy &quot;%sourceDir%&quot; &quot;%targetDir%&quot; /E /L /FP /NJH /NJS /NDL /NS /NC /XO /XX /LOG:&quot;%logFile%&quot;

rem Показать содержимое лог-файла для проверки
echo Содержимое лог-файла:
type &quot;%logFile%&quot;

rem Чтение лога и копирование измененных файлов
for /f &quot;tokens=*&quot; %%i in (&#039;type &quot;%logFile%&quot;&#039;) do (
    set &quot;line=%%i&quot;
    rem Удаление начальных пробелов
    set &quot;filePath=!line:~14!&quot;

    rem Проверка, что строка не пустая
    if not &quot;!filePath!&quot; == &quot;&quot; (
        echo Обработка файла: !filePath!

        rem Получение полного пути файла относительно исходного каталога
        set &quot;relativeFilePath=!filePath:%sourceDir%\=!&quot;

        rem Полный путь к файлу в целевом каталоге
        set &quot;backupFile=%backupDir%\!relativeFilePath!&quot;
        
        rem Директория файла в целевом каталоге
        set &quot;backupFileDir=!backupFile!&quot;
        for %%k in (&quot;!backupFileDir!&quot;) do set &quot;backupFileDir=%%~dpk&quot;
        
        if not exist &quot;!backupFileDir!&quot; (
            echo Создание каталога: &quot;!backupFileDir!&quot;
            mkdir &quot;!backupFileDir!&quot;
        )

        echo Копирование файла: &quot;%sourceDir%\!relativeFilePath!&quot; в &quot;!backupFileDir!&quot;
        robocopy &quot;%sourceDir%&quot; &quot;!backupFileDir!&quot; &quot;!relativeFilePath!&quot; /COPYALL /R:0 /W:0

        echo Команда robocopy завершена с кодом ошибки: %ERRORLEVEL%
    )
)

echo Копирование измененных файлов завершено.
endlocal
pause
</code></pre></div><p>Но к сожалению не могу понять почему он не работает.<br />Лог файл создается измененные файлы туда заносятся но копирования не происходит, возможно у кого-то есть более здравая мысль как это реализовать корректнее и надежнее…<br />Также необходимо учитывать что robocopy взят по причине присутствия длинных имен и каталогов.</p>]]></description>
			<author><![CDATA[null@example.com (grisha.puding)]]></author>
			<pubDate>Sat, 01 Jun 2024 21:29:43 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18212&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Любые действия с курсором]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18162&amp;action=new</link>
			<description><![CDATA[<p>Здравствуйте! При запуске Windows сразу открывается программа, которая скрывает курсор, при взаимодействии с курсором любым после запуска программы - курсор появляется ( взаимодействия - к примеру показ скрытие курсора на CTRL такая функция или смена дизайна курсора в настройках ), так вот надо сделать я так думаю что-то типа .bat файла чтобы после запуска программы или через несколько секунд какие либо манипуляции с курсором были для его появления.</p>]]></description>
			<author><![CDATA[null@example.com (gulyaev-d.2015)]]></author>
			<pubDate>Mon, 08 Apr 2024 14:21:03 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18162&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: выполнить команду при закрытии окна сценария]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?id=18061&amp;action=new</link>
			<description><![CDATA[<p>Здравствуйте.<br />В организации с помощью сторонней утилиты объединяются PDF файлы в один внутри одной папки.<br />Из-за структуры названий пути получаются довольно большими, из-за чего в сценарий заложено создание диска по команде &quot;subst&quot; и работы уже в нём.<br />Коротко:<br /></p><div class="codebox"><pre><code>subst i: &quot;d:\&quot;</code></pre></div><p>С последующим размонтированием, если всё прошло успешно.<br /></p><div class="codebox"><pre><code>subst i: /d</code></pre></div><p>Как при возникновении ошибки и закрытии окна по клавише &quot;Esc&quot; или по крестику сделать так, чтобы созданный диск &quot;subst&quot; размонтировался?<br />Возможно ли прописать действия на условие закрытия окна внутри BAT файла?</p><p>Думал на внешнее решение - Планировщик Windows, но тогда ему надо как то передать букву диска.&nbsp; Буква диска у меня в скрипте назначается автоматически из свободных, если существующий занят, поэтому на разных ПК буква может быть разная.</p>]]></description>
			<author><![CDATA[null@example.com (berstrider)]]></author>
			<pubDate>Fri, 12 Jan 2024 11:21:39 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?id=18061&amp;action=new</guid>
		</item>
	</channel>
</rss>
