Войти

Показать полную графическую версию : [решено] Поиск в файле и запись в переменную


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

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

Elven
25-11-2019, 13:01
1. на cmd это решается долго, нудно, паскудно. Если есть возможность - лучше смотреть в пошик (обычно такая возможность есть, если нет - аргументы в студию). Вот даже здесь (http://forum.oszone.net/thread-336681.html) похожая задача решалась.
2. сейчас (а возможно даже уже) в тему заглянет Iska и затребует пример файла, или как минимум задаст вполне справедливые вопросы по кодироке и окончанию строк.

megaloman
25-11-2019, 13:14
@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
Очередной вариант создания искусственного интеллекта на 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
Единственное не могу понять где в переменной Select появляется пробел в конце строки? »
Например, вот здесь:
https://i.imgur.com/OGsICSZ.png

megaloman
25-11-2019, 16:55
Единственное не могу понять где в переменной Select появляется пробел в конце строки? »Виноват, спешка, присваивание надо делать в кавычках If %NN% GEQ 1 If %NN% LEQ %i% (Call Set "Select=%%@@%NN%%%" &GoTo :End)

V!RTuE
01-01-2023, 22:41
megaloman, прошу помочь доработать ваш код.
Имеется текстовый файл следующего содержания:
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
@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
megaloman, еще просьба есть. Возможно ли добавить сюда сортировку по имени в алфавитном порядке?
А так большое спасибо. Код работает отлично!

megaloman
09-01-2023, 17:48
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
megaloman, если в искомом файле нет записей о клиентских сертификатах, то появляется надпись:
Переменная среды x@@ не определена
Как ее можно убрать?
В остальном всё прекрасно работает :good:

V!RTuE
09-01-2023, 23:48
Разобрался вроде.
Добавил в начале:
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
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
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 (http://forum.oszone.net/thread-352754.html)
Если будет желание и время разобраться, то прошу ознакомиться. Лучше там продолжить обсуждение.




© OSzone.net 2001-2012