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

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

ownsmir 25-11-2019 11:15 2897881

Поиск в файле и запись в переменную
 
Доброго времени суток Уважаемые!
Есть задача: Нужно в файле средствами CMD найти все строки совпадающие с заданным условием поиска в переменной %name% (это текст фамилия или часть названия организации) и ВСЕ найденные строки записать каждую в свою переменную для дальнейшего выбора пользователя нужной переменной (в виде cmd под цифрами 1,2,3 и т.д.) Пользователь выбирает и процесс идет дальше.

В принципе к Вам вопрос о том: каким образом записать все найденные варианты в каждый в свою переменную и сделать выбор под цифрами полученных результатов...

Elven 25-11-2019 13:01 2897901

1. на cmd это решается долго, нудно, паскудно. Если есть возможность - лучше смотреть в пошик (обычно такая возможность есть, если нет - аргументы в студию). Вот даже здесь похожая задача решалась.
2. сейчас (а возможно даже уже) в тему заглянет Iska и затребует пример файла, или как минимум задаст вполне справедливые вопросы по кодироке и окончанию строк.

megaloman 25-11-2019 13:14 2897906

Очередной вариант создания искусственного интеллекта на CMD
Код:

@Echo Off
cls
        >nul Chcp 1251
       
        Set "FileIn=Z:\Box_In\Нужно в файле.txt"
        Set "name=СоБаКа"

        If Not Exist "%FileIn%" (
                Echo Файл "%FileIn%" не найден. &Echo.
                Pause
                Exit /B 2
        )

        Set /A i=0

        Echo Выбирайте номер варианта N (Enter -завершение работы):
        Echo.
        For /F "usebackq Skip=2 delims=" %%s In (`2^>nul Find /I "%name%" "%FileIn%"`) Do (
                Call Set /A i+=1
                Call Set "@@%%i%%=%%s"
                Call Echo %%i%%= %%s
        )
        If %i%==0 (
                Echo Подстрока "%name%" в файле "%FileIn%" не найдена  &Echo.
                Pause
                Exit /B 1
        )

        :Begin
                Echo.
                Set "NN="
                Set /P NN=N=
                If "%NN%"=="" Exit /B 0
                If %NN% GEQ 1 If %NN% LEQ %i% (Call Set "Select=%%@@%NN%%%" &GoTo :End)
                Echo Введено неверное значение "%NN%", введите верное: &GoTo :Begin
        :End
        Echo %Select%

Pause
Exit /B 0

Предполагал, что текстовый файл в кодировке 1251, следовательно и батник должен быть в кодировке 1251

ownsmir 25-11-2019 14:55 2897921

Цитата:

Цитата megaloman
Очередной вариант создания искусственного интеллекта на CMD
Код:
@Echo Off
cls
>nul Chcp 1251
Set "FileIn=Z:\Box_In\Нужно в файле.txt"
Set "name=СоБаКа"
If Not Exist "%FileIn%" (
Echo Файл "%FileIn%" не найден. &Echo.
Pause
Exit /B 2
)
Set /A i=0
Echo Выбирайте номер варианта N (Enter -завершение работы):
Echo.
For /F "usebackq Skip=2 delims=" %%s In (`2^>nul Find /I "%name%" "%FileIn%"`) Do (
Call Set /A i+=1
Call Set "@@%%i%%=%%s"
Call Echo %%i%%= %%s
)
If %i%==0 (
Echo Подстрока "%name%" в файле "%FileIn%" не найдена &Echo.
Pause
Exit /B 1
)
:Begin
Echo.
Set "NN="
Set /P NN=N=
If "%NN%"=="" Exit /B 0
If %NN% GEQ 1 If %NN% LEQ %i% (Call Set Select=%%@@%NN%%% &GoTo :End)
Echo Введено неверное значение "%NN%", введите верное: &GoTo :Begin
:End
Echo %Select%
Pause
Exit /B 0
Предполагал, что текстовый файл в кодировке 1251, следовательно и батник должен быть в кодировке 1251 »

Наконец то супер)))) Спасибо огромноее!! Единственное не могу понять где в переменной Select появляется пробел в конце строки?

Iska 25-11-2019 15:04 2897927

Цитата:

Цитата ownsmir
Единственное не могу понять где в переменной Select появляется пробел в конце строки? »

Например, вот здесь:
Скрытый текст

megaloman 25-11-2019 16:55 2897945

Цитата:

Цитата ownsmir
Единственное не могу понять где в переменной Select появляется пробел в конце строки? »

Виноват, спешка, присваивание надо делать в кавычках
Код:

                If %NN% GEQ 1 If %NN% LEQ %i% (Call Set "Select=%%@@%NN%%%" &GoTo :End)

V!RTuE 01-01-2023 22:41 3000083

megaloman, прошу помочь доработать ваш код.
Имеется текстовый файл следующего содержания:
index.txt
V 321223032921Z 01 unknown /C=RU/ST=Msk/L=Msk/O=MyOrg/OU=server/CN=server/name=server/emailAddress=mail@mail.ru
V 321223032955Z 02 unknown /C=RU/ST=Msk/L=Msk/O=MyOrg/OU=server/CN=admin/name=server/emailAddress=mail@mail.ru
V 321223035016Z 03 unknown /C=RU/ST=Msk/L=Msk/O=MyOrg/OU=server/CN=user1/name=server/emailAddress=mail@mail.ru
V 321223035451Z 04 unknown /C=RU/ST=Msk/L=Msk/O=MyOrg/OU=server/CN=user2/name=server/emailAddress=mail@mail.ru
R 321223041103Z 05 unknown /C=RU/ST=Msk/L=Msk/O=MyOrg/OU=server/CN=user3/name=server/emailAddress=mail@mail.ru
V 321223043210Z 06 unknown /C=RU/ST=Msk/L=Msk/O=MyOrg/OU=server/CN=user4/name=server/emailAddress=mail@mail.ru
V 321223045105Z 07 unknown /C=RU/ST=Msk/L=Msk/O=MyOrg/OU=server/CN=user5/name=server/emailAddress=mail@mail.ru

Требуется вывести нумерованный список пользовательских сертификатов (начиная со 2-ой строки, значение CN= до следующего разделителя /), кроме сертификата сервера (это первая строка) и к названию сертификата добавить [ОТОЗВАН], при условии, что первая буква в соответствующей имени сертификата строке, будет R. Если V, то ничего не добавлять к имени. Как это реализовать?
Просто вывести список пользовательских сертификатов получилось так, взяв за основу ваш код:
Код:

@Echo Off
cls
        >nul Chcp 1251
       
        Set "indextxt=C:\Program Files\OpenVPN\easy-rsa\keys\index.txt"
        Set "word=name"

        If Not Exist "%indextxt%" (
                Echo Файл "%indextxt%" не найден. &Echo.
                Pause
                Exit /B 2
        )

        Set /A i=0

        Echo Введите номер, соответствующий сертификату, который требуется отозвать (Enter - завершение работы):
        Echo.
        For /F "usebackq tokens=13 Skip=3 delims=/=" %%s In (`2^>nul Find /I "%word%" "%indextxt%"`) Do (
                Call Set /A i+=1
                Call Set "@@%%i%%=%%s"
                Call Echo %%i%%. %%s
        )
        )
        If %i%==0 (
        cls
                Echo Пользовательские сертификаты не найдены  &Echo.
                Pause
                Exit /B 1
        )

        :Begin
                Echo.
                Set "NN="
                Set /P NN=N=
                If "%NN%"=="" Exit /B 0
                If %NN% GEQ 1 If %NN% LEQ %i% (Call Set "Select=%%@@%NN%%%" &GoTo :End)
                Echo Введено неверное значение "%NN%", введите верное: &GoTo :Begin
        :End
        Echo вы выбрали: %Select%

Pause
Exit /B 0

В итоге должно получиться так:
Цитата:

Введите номер, соответствующий сертификату, который требуется отозвать (Enter - завершение работы):

1. admin
2. user1
3. user2
4. user3 [ОТОЗВАН]
5. user4
6. user5

N=
и при выборе номера отображалось сообщение:
Цитата:

Вы выбрали %cert_name%
P.S.: powershell прошу не предлагать. крайне желательно именно средствами bat/cmd сделать.

megaloman 02-01-2023 07:51 3000087

Код:

@Echo Off
cls
>nul Chcp 1251
        Set "FileIn=Z:\Program Files\OpenVPN\easy-rsa\keys\index.txt"

        If Not Exist "%FileIn%" (Echo Файл "%FileIn%" не найден. &Echo. &Pause &Exit /B 2)
       
        Set /A y=0
        FOR /F "usebackq skip=1 tokens=1,7 delims=/" %%i In ("%FileIn%") DO (
                Set /A y+=1
                Set "xx=%%j"
                Call Set "@@%%y%%=%%xx:~3%%"
                Echo %%i| >nul 2>nul FindStr /B /I /C:"R"&&Call Set "@@%%y%%=%%xx:~3%% [ОТОЗВАН]"
        )
        If %y% EQU 0 (Echo Пользовательские сертификаты не найдены. &Echo. &Pause &Exit /B 1)

        Echo Введите номер, соответствующий сертификату, который требуется отозвать (Enter - завершение работы):
        Echo.
        FOR /L %%i In (1,1,%y%) Do (Set "xx=    %%i"&Call Echo %%xx:~-4%%. %%@@%%i%%)

        :Begin
                Echo.
                Set "NN="
                Set /P NN=Выбираем номер N=
                If "%NN%"=="" Exit /B 0
                If 1 LEQ %NN% If %NN% LEQ %y% (Call Set "Select=%%@@%NN%%%" &GoTo :End)
                Echo Введено неверное значение "%NN%", введите верное: &GoTo :Begin
        :End
        Echo вы выбрали: "%Select%"
pause
Exit /B


V!RTuE 09-01-2023 07:05 3000540

megaloman, еще просьба есть. Возможно ли добавить сюда сортировку по имени в алфавитном порядке?
А так большое спасибо. Код работает отлично!

megaloman 09-01-2023 17:48 3000570

V!RTuE,
Код:

@Echo Off
cls
>nul Chcp 1251
        Set "FileIn=Z:\Program Files\OpenVPN\easy-rsa\keys\index.txt"

        If Not Exist "%FileIn%" (Echo Файл "%FileIn%" не найден. &Echo. &Pause &Exit /B 2)
       
        Set /A y=0
        FOR /F "usebackq skip=1 tokens=1,7 delims=/" %%i In ("%FileIn%") DO (
                Set /A y+=1
                Set "xx=%%j"
                Call Set "x@@%%xx:~3%%=%%xx:~3%%"
                Echo %%i| >nul 2>nul FindStr /B /I /C:"R"&&Call Set "x@@%%xx:~3%%=%%xx:~3%% [ОТОЗВАН]"
        )
        If %y% EQU 0 (Echo Пользовательские сертификаты не найдены. &Echo. &Pause &Exit /B 1)

        Set /A y=0
        FOR /F "usebackq tokens=2 delims==" %%i In (`Set "x@@"^|Sort`) DO (
                Set /A y+=1
                Call Set "@@%%y%%=%%i"
        )

        Echo Введите номер, соответствующий сертификату, который требуется отозвать (Enter - завершение работы):
        Echo.
        FOR /L %%i In (1,1,%y%) Do (Set "xx=    %%i"&Call Echo %%xx:~-4%%. %%@@%%i%%)

        :Begin
                Echo.
                Set "NN="
                Set /P NN=Выбираем номер N=
                If "%NN%"=="" Exit /B 0
                If 1 LEQ %NN% If %NN% LEQ %y% (Call Set "Select=%%@@%NN%%%" &GoTo :End)
                Echo Введено неверное значение "%NN%", введите верное: &GoTo :Begin
        :End
        Echo вы выбрали: "%Select%"
pause
Exit /B


V!RTuE 09-01-2023 23:15 3000599

megaloman, если в искомом файле нет записей о клиентских сертификатах, то появляется надпись:
Цитата:

Переменная среды x@@ не определена
Как ее можно убрать?
В остальном всё прекрасно работает :good:

V!RTuE 09-01-2023 23:48 3000601

Разобрался вроде.
Добавил в начале:
Код:

set "xx="
и далее добавил проверку:
Код:

if "%xx%" == "" GoTo :SKIP
Полностью код выглядит у меня так:
Код:

:: Показать список клиентов
        CALL :EchoColor 6 "        Список клиентов:"&echo.
        echo.
        set "xx="
        Set /A y=0
        FOR /F "usebackq skip=1 tokens=1,7 delims=/" %%i In ("%indextxt%") DO (
                Set /A y+=1
                Set "xx=%%j"
                Call Set "x@@%%xx:~3%%=%%xx:~3%%"
                Echo %%i| >nul 2>nul FindStr /B /I /C:"R"&&Call Set "x@@%%xx:~3%%=%%xx:~3%% [ОТОЗВАН]"
        )
        If %y% EQU 0 (CALL :EchoColor 4 "[X] Клиентские сертификаты [НЕ НАЙДЕНЫ]"&echo. &echo.)
       
        if "%xx%" == "" GoTo :SKIP
       
        Set /A y=0
        FOR /F "usebackq tokens=2 delims==" %%i In (`Set "x@@"^|Sort`) DO (
                Set /A y+=1
                Call Set "@@%%y%%=%%i"
        )
       
        FOR /L %%i In (1,1,%y%) Do (Set "xx=    %%i"&Call Echo %%xx:~-4%%. %%@@%%i%%)
       
        :SKIP


megaloman 10-01-2023 12:35 3000623

V!RTuE, ИМХО, надо так:
Код:

@Echo Off
cls
>nul Chcp 1251
        Set "FileIn=Z:\Program Files\OpenVPN\easy-rsa\keys\index.txt"

        If Not Exist "%FileIn%" (Echo Файл "%FileIn%" не найден. &Echo. &Pause &Exit /B 2)

        FOR /F "usebackq skip=1 tokens=1,7 delims=/" %%i In ("%FileIn%") DO (
                Set "xx=%%j"
                Call Set "x@@%%xx:~3%%=%%xx:~3%%"
                Echo %%i| >nul 2>nul FindStr /B /I /C:"R"&&Call Set "x@@%%xx:~3%%=%%xx:~3%% [ОТОЗВАН]"
        )
        >nul 2>&1 Set "x@@" ||(Echo Пользовательские сертификаты не найдены. &Echo. &Pause &Exit /B 1)

        Set /A y=0
        FOR /F "usebackq tokens=2 delims==" %%i In (`Set "x@@"^|Sort`) DO (
                Set /A y+=1
                Call Set "@@%%y%%=%%i"
        )

        Echo Введите номер, соответствующий сертификату, который требуется отозвать (Enter - завершение работы):
        Echo.
        FOR /L %%i In (1,1,%y%) Do (Set "xx=    %%i"&Call Echo %%xx:~-4%%. %%@@%%i%%)

        :Begin
                Echo.
                Set "NN="
                Set /P NN=Выбираем номер N=
                If "%NN%"=="" Exit /B 0
                If 1 LEQ %NN% If %NN% LEQ %y% (Call Set "Select=%%@@%NN%%%" &GoTo :End)
                Echo Введено неверное значение "%NN%", введите верное: &GoTo :Begin
        :End
        Echo вы выбрали: "%Select%"
pause
Exit /B


V!RTuE 10-01-2023 14:41 3000627

megaloman, всё-равно появляется ошибка. Так как у меня в 2 местах подобный скрипт используется. Первое - это когда надо отозвать сертификат, то там при не нахождении искомой записи скрипт должен завершить работу (точнее вернуться в предыдущий пункт меню).
И второй случай это при создании нового сертификата у меня показывается нумерованный список уже имеющихся, но не без необходимости с ними что-либо делать. Эту часть кода я убрал:
Скрытый текст
Код:

:Begin
                Echo.
                Set "NN="
                Set /P NN=Выбираем номер N=
                If "%NN%"=="" Exit /B 0
                If 1 LEQ %NN% If %NN% LEQ %y% (Call Set "Select=%%@@%NN%%%" &GoTo :End)
                Echo Введено неверное значение "%NN%", введите верное: &GoTo :Begin
        :End
        Echo вы выбрали: "%Select%"


поэтому если и не найдено записей, то я решил, что проще пропустить часть кода, сделав соответствующую метку и перейдя сразу к ней. Ну и надо учитывать, что не закрывая скрипт может потребоваться несколько раз выполнять этот код. и могут как присутствовать записи о сертификатах, так и нет. Чтобы не принимало %xx% старое значение я каждый раз присваиваю ему пустое значение.
Вот исправил, как вы написали.
Исполняемый код:
Код:

        :: Показать список клиентов
        CALL :EchoColor 6 "        Список клиентов:"&echo.
        echo.
        FOR /F "usebackq skip=1 tokens=1,7 delims=/" %%i In ("%indextxt%") DO (
                Set "xx=%%j"
                Call Set "x@@%%xx:~3%%=%%xx:~3%%"
                Echo %%i| >nul 2>nul FindStr /B /I /C:"R"&&Call Set "x@@%%xx:~3%%=%%xx:~3%% [ОТОЗВАН]"
        )
        >nul 2>&1 Set "x@@" ||(CALL :EchoColor 4 "[X] Клиентские сертификаты [НЕ НАЙДЕНЫ]"&echo. &echo.)
       
        Set /A y=0
        FOR /F "usebackq tokens=2 delims==" %%i In (`Set "x@@"^|Sort`) DO (
                Set /A y+=1
                Call Set "@@%%y%%=%%i"
        )
       
        FOR /L %%i In (1,1,%y%) Do (Set "xx=    %%i"&Call Echo %%xx:~-4%%. %%@@%%i%%)
       
        :SKIP
        CALL :EchoColor 3 "================================================================================"&echo.
        echo.


Вот результат:
Цитата:

Список клиентов:

[X] Клиентские сертификаты [НЕ НАЙДЕНЫ]

Переменная среды x@@ не определена
================================================================================

P.S.: Опубликовал полностью свой проект :lamer: OpenVPN-All-in-One - Скрипт,облегчающий создание серверной и клиентской части OpenVPN
Если будет желание и время разобраться, то прошу ознакомиться. Лучше там продолжить обсуждение.


Время: 21:31.

Время: 21:31.
© OSzone.net 2001-