Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Как взять в цикл FOR имена изнутри самого исполняемого CMD (http://forum.oszone.net/showthread.php?t=356243)

alexys2004 11-04-2025 07:07 3037159

Как взять в цикл FOR имена изнутри самого исполняемого CMD
 
Здравия всем!
Уважаемые знатоки, требуется ваша помощь!
Есть стандартный цикл, который берёт из внешнего файла имена и записывает их в другой файл!
Пока этих файлов была пара, было терпимо, а теперь россыпь из десятка файлов начинает раздражать! :(
Возможно ли сделать так, чтобы цикл брал имена из списка внутри самого исполняемого CMD ?
Например, цикл обращается к некоему списку имён, который прячется в конце файла после EXIT и дальше записывает их во внешний файл..

PHP код:

SET NAME=:список
FOR /"usebackq tokens=* delims=" %%i IN ("%NAME%") DO (ECHO %%i>> файл.txt)
EXIT

:
список откуда брать имена
ИМЯ1
ИМЯ2
ИМЯ3 

Крайне благодарен, если есть решение!

NickM 11-04-2025 07:33 3037160

Не совсем список, но, работает:
Код:

@echo off
SetLocal EnableExtensions EnableDelayedExpansion

SET "len=5"
FOR /l %%i IN (1,1,%len%) DO (
call :NAME%%i
ECHO. !name! >> файл.txt
)
goto :EOF
exit

:NAME1
set "name=ИМЯ1"
goto :EOF

:NAME2
set "name=ИМЯ2"
goto :EOF

:NAME3
set "name=ИМЯ3"
goto :EOF

:NAME4
set "name=ИМЯ4"
goto :EOF

:NAME5
set "name=ИМЯ5"
goto :EOF

А, вообще, вариантов много можно придумать, например, с тем же временным файлом, в который список помещать, а после его читать и прочее.

alexys2004 11-04-2025 07:49 3037161

Такой вариант у меня уже был, очень трудно искать и редактировать список имён!

Что касается "временного файла" - тоже думал, но в крайнем случае.. проще, наверное, всю эту россыпь в архив собрать.

Нужен, если есть, именно вариант с обращением к голому списку внутри самого CMD ?

NickM 11-04-2025 08:48 3037163

Цитата:

Цитата alexys2004
Что касается "временного файла" - тоже думал, но в крайнем случае.. проще, наверное, всю эту россыпь в архив собрать. »

Никакой россыпи, например:
Код:

@echo off
SET "file_with_name=%temp%\file_with_name.txt"
more +9 "%~0">"%file_with_name%"

FOR /F "usebackq tokens=* delims=" %%i IN ("%file_with_name%") DO (ECHO %%i)
del /f /q "%file_with_name%"
EXIT

:список имён
ИМЯ1
ИМЯ2
ИМЯ33
ИМЯ4
ИМЯ5


alexys2004 11-04-2025 10:28 3037166

Не очень понял - в какой момент имена из раздела ":список имён" выносятся во временный файл?

и что делает операция:
more +9 "%~0">"%file_with_name%"

И ещё, я забыл сделать акцент в первом посте:
таких списков будет НЕ один, т.к. внешних файлов уже почти десяток - вот от них я хочу избавиться и засунуть все списки в один исполняемый файл, но каждый отдельно, чтобы обрабатывался по мере необходимости!
Собрать всё в один список - не вариант! надо, чтобы создавался в нужный момент отдельный файл с отдельным списком, взятым из конкретной области в исполняемом файле!

PHP код:

SET NAME=:список 1
FOR /"usebackq tokens=* delims=" %%i IN ("%NAME%") DO (ECHO %%i>> файл.txt)
SET NAME=:список 2
FOR /"usebackq tokens=* delims=" %%i IN ("%NAME%") DO (ECHO %%i>> файл.txt)
EXIT

:
список 1
ИМЯ11
ИМЯ12
ИМЯ13

:список 2
ИМЯ21
ИМЯ22
ИМЯ23 


NickM 11-04-2025 10:40 3037168

Цитата:

Цитата alexys2004
И ещё, я забыл сделать акцент в первом посте:
таких списков будет НЕ один »

Это акцентище!

Цитата:

Цитата alexys2004
Не очень понял - в какой момент имена из раздела ":список имён" выносятся во временный файл? »

Цитата:

Цитата alexys2004
и что делает операция:
more +9 "%~0">"%file_with_name%" »

Именно это и делает - наполняет временный файл списком;

Цитата:

Цитата alexys2004
Собрать всё в один список - не вариант! надо, чтобы создавался в нужный момент отдельный файл с отдельным списком, взятым из конкретной области в исполняемом файле! »

Можно наверное и здесь что-нибудь придумать.

Sham 11-04-2025 12:52 3037170

если список брать из внутренней переменной, то переносы нужно экранировать, оставляя пробелы между именами
Код:

@echo off
goto set_list1
:do
for %%i in (%LIST%) do echo "%%i"
pause
exit

:set_list1
set LIST=ИМЯ11^
 ИМЯ12^
 ИМЯ13
goto do

иначе нужно читать сам этот скрипт извне и искать в нём текст этого списка либо построчным поиском, либо регулярным выражением. Тут уже надо определяться с языком скрипта или утилитами типа grep, которых нет в системе.

DJ Mogarych 11-04-2025 12:57 3037171

Powershell, запрос номера списка и вывод в файл.
Код:

$list1 = ("
ИМЯ11
ИМЯ12
ИМЯ13
") -split "`n" -match "\w"

$list2 = ("
ИМЯ21
ИМЯ22
ИМЯ23
") -split "`n" -match "\w"

$list3 = ("
ИМЯ31
ИМЯ32
ИМЯ33
") -split "`n" -match "\w"

$l = read-host "Номер списка для вывода в файл"
switch ($l) {
    1 {$selectedList = $list1}
    2 {$selectedList = $list2}
    3 {$selectedList = $list3}
}
$selectedList |out-file "c:\temp\file.txt" -Encoding default


NickM 11-04-2025 13:36 3037173

Цитата:

Цитата NickM
Можно наверное и здесь что-нибудь придумать. »

Изврат какой-то получился, но вроде работает как того требуется - списки в файле, обрамлены концом и началом:
Код:

@echo off
SetLocal EnableExtensions EnableDelayedExpansion
set /p "spisok=Ведите № списка:"

for /f "tokens=* delims=" %%i in ('more "%~0" ^| findstr /n "begin_%spisok%"') do (
set "b=%%i"
set "b=!b:::begin_%spisok%=!"
)

for /f "tokens=* delims=" %%i in ('more +%b% "%~0"') do (
if "%%i" NEQ ":end_%spisok%" (echo. %%i)
if "%%i" EQU ":end_%spisok%" goto :EOF
)

:begin_1
ИМЯ11
ИМЯ12
ИМЯ13
:end_1

:begin_2
ИМЯ21
ИМЯ22
ИМЯ23
ИМЯ24
:end_2

:begin_3
ИМЯ31
ИМЯ32
ИМЯ33
:end_3

:begin_4
ИМЯ41
ИМЯ42
:end_4

:begin_5
ИМЯ51
ИМЯ52
ИМЯ53
ИМЯ54
ИМЯ55
:end_5


megaloman 11-04-2025 16:59 3037183

Код:

@Echo Off &Cls
        Set "BoxOut=Z:\Box_Out"

        Set "@S1=File1.txt"
        Set "@S2=File2.txt"
        Set "@S3=File3.txt"
        Set "@S12345=File777.txt"
               
        Pushd "%BoxOut%"||(Echo Folder "%BoxOut%" not found &Pause &Exit /B 2)
        For /f "usebackq tokens=1* delims==" %%i IN (`Set "@S"`) Do >nul 2>&1 Del "%BoxOut%\%%j"
        For /f "usebackq tokens=1* delims=:" %%i IN (`FindStr /R /N /C:"^:@S" "%~dpnx0"`) Do Call :Out %%i %%j
Pause
Exit /B

:Out
        Call Set "OutFile=%%%2%%"
        For /f "usebackq delims=" %%s IN (`More +%1 "%~dpnx0"`) Do (
                Echo "%%s"|>nul Find ":@S"&&Exit /B
                >>"%BoxOut%\%OutFile%" Echo %%s
        )
Exit /B

:@S1
C:\Program Files\1 skjhdk kslhjdljsl sl;djl;jlsjd.txt
C:\Program Files\Advanced IP Scanner\2 sslm jds;ll; dalj;al lajl;akjsl;ka.png
C:\Program Files (x86)\3 aklljalkjs akjslkajlasjl akljlakjljs.dbf

:@S2
C:\Program Files\4 adSA SDASD DADADD.xls
C:\Program Files (x86)\5 aSDFDSA CSAS SAASAS.doc

:@S12345
8 adSA SDASD DADADD.xls
9 aSDFDSA CSAS SAASAS.doc

:@S3
C:\Program Files (x86)\6 adSA SDASD DADADD.xls
C:\Program Files\7 aSDFDSA CSAS SAASAS.doc

1. Списки должны быть последними в батнике.
2. Перед списками обязательно должен быть Exit
3. Список должен именоваться @Sxxxx и начинаться :@Sxxxx
4. Для каждого списка должно указываться имя выходного файла. Для разных списков выходной файл может совпадать.

В примере списков имена файлов абсолютно условны и могут быть как с путями, так и без - это уже тонкости, не указанные постановкой

alexys2004 12-04-2025 06:28 3037196

DJ Mogarych,
Цитата:

Цитата DJ Mogarych
Powershell, запрос номера списка и вывод в файл. »

немного не то! да и Powershell я совсем плохо понимаю.. :sorry:

megaloman,
это прям КРУТО! :up
только я не совсем ещё понял, как это работает..
надо разобраться, как записывать не все файлы сразу, а нужный в конкретный момент..
можно я попробую разобраться и ещё раз Вас спрошу, если понадобится?

megaloman,
если я правильно понял, цикл

PHP код:

For /"usebackq tokens=1* delims=:" %%i IN (`FindStr /R /N /C:"^:@S" "%~dpnx0"`) Do Call :Out %%%%

находит все @S, вызывает функцию, которая записывает найденные имена в файлы, которые созданы строкой выше?

а если в конкретный момент времени мне надо записать имена из конкретного списка в конкретный файл, то мне достаточно только самой функции :Out без перебора всех списков в цикле? только нужно подставить конкретные имена вместо переменных в этот цикл, опустив предыдущие 2 цикла перебора файлов и списков?

PHP код:

Call Set "OutFile=%%%2%%"
    
For /"usebackq delims=" %%s IN (`More +%1 "%~dpnx0"`) Do (
        Echo 
"%%s"|>nul Find ":@S"&&Exit /B
        
>>"%BoxOut%\%OutFile%" Echo %%


alexys2004 12-04-2025 07:04 3037199

megaloman,

сократил вот так:

PHP код:

@Echo Off &Cls
    Set 
"BoxOut=D:\Box_Out"

    
For /"usebackq tokens=1* delims=:" %%i IN (`FindStr /R /N /C:"^:@S1" "%~dpnx0"`) Do Call :Out %%%%j
Pause
Exit /B

:Out
    
For /"usebackq delims=" %%s IN (`More +%1 "%~dpnx0"`) Do (
        Echo 
"%%s"|>nul Find ":@S"&&Exit /B
        
>>"%BoxOut%\list1.txt" Echo %%s
    
)
Exit /
B

:@S1
C
:Program Files1 skjhdk kslhjdljsl sl;djl;jlsjd.txt
C
:Program FilesAdvanced IP Scanner2 sslm jds;lldalj;al lajl;akjsl;ka.png
C
:Program Files (x86)3 aklljalkjs akjslkajlasjl akljlakjljs.dbf

:@S2
C
:Program Files4 adSA SDASD DADADD.xls
C
:Program Files (x86)5 aSDFDSA CSAS SAASAS.doc 

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

Sham 12-04-2025 10:47 3037204

Цитата:

Цитата alexys2004
FindStr*/R*/N*/C:"^:@S1 »

насколько понял, ищется в этом файле скрипта строка содержащая ":@S" (заголовок списка), и в функцию передаётся номер строки и сама строка целиком (вывод FindStr, разделённый по delim). Дальше more позволяет начать чтение файла с этого номера строки. Чтобы конкретизировать список нужно передать в FindStr более конкретный заголовок списка, а не :@S.

megaloman 12-04-2025 11:08 3037205

Код:

@Echo Off &Cls
        If Not "%~1"=="" If Not "%~2"=="" GoTo :Begin
                Echo The script arguments must contain the name of the list and the name of the output file!
                Echo Script terminated! &Pause &Exit /B 2
        :Begin
                If Not Exist "%~dp2" (Echo Folder "%~dp2" not found &Pause &Exit /B 2) Else (2>nul Del "%~dpnx1")
                Set /A n=-1
                For /f "usebackq tokens=1* delims=:" %%i IN (`FindStr /I /R /N /C:"^:%~1$" "%~dpnx0"`) Do Set /A n=%%i
                If %n% LSS 0 (Echo List "%~1" not found &Pause &Exit /B 2)
                For /f "usebackq delims=" %%s IN (`More +%n% "%~dpnx0"`) Do (
                        Echo "%%s"|>nul Find /I ":@S"&&(Pause &Exit /B)
                        >>"%~2" Echo %%s
                )
Pause
Exit /B

:@S1
C:\Program Files\1 skjhdk kslhjdljsl sl;djl;jlsjd.txt
C:\Program Files\Advanced IP Scanner\2 sslm jds;ll; dalj;al lajl;akjsl;ka.png
C:\Program Files (x86)\3 aklljalkjs akjslkajlasjl akljlakjljs.dbf

:@S2
C:\Program Files\4 adSA SDASD DADADD.xls
C:\Program Files (x86)\5 aSDFDSA CSAS SAASAS.doc

:@S12345
8 adSA SDASD DADADD.xls
9 aSDFDSA CSAS SAASAS.doc

:@S3
C:\Program Files (x86)\6 adSA SDASD DADADD.xls
C:\Program Files\7 aSDFDSA CSAS SAASAS.doc

Имя списка и выходной файл передаются в аргументах.


Время: 03:20.

Время: 03:20.
© OSzone.net 2001-