PDA

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


Patroklos
05-02-2018, 17:36
Здравствуйте, подскажите какие способы есть отправить в переменную часть строки?
Например строкаfast slow error password error garbage test text blabla
я хочу получить в переменной var слово password.
флагом будет слово error меду которыми находиться нужная информация.
Какие варианты есть? FOR такой делимитер можно подсунуть?
Или findstr регуляркой какой нибудь можно вытащить?
Делимитер очень желательно слово или ряд символов. Например ###

alpap
06-02-2018, 12:13
допустим так, хоть и не коротко:

@echo off
set "s=fast slow error password error garbage test text blabla"
set "teg=error"
set "f_in=file.txt"

>"%f_in%" (for %%a in (%s%) do @echo %%a)
setlocal enabledelayedexpansion
<"%f_in%" (for /f "delims=[]" %%a in ('find /n "%teg%"') do @set/a n+=1& set s!n!=%%a& set/a nd=s1+1,kd=s2-1)
<"%f_in%" (for /f "delims=" %%a in ('for /l %%a in ^(%nd%,1,%kd%^) do @find /n /v ""^|find "[%%a]"') do @set "s=%%a"& set "var=!s:*]=!")
setlocal disabledelayedexpansion
echo %var%
pause
exit


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

кстати подобное PoSh сделает на ура и моргнуть не успеете.

Patroklos
06-02-2018, 13:37
Спасибо, пока правда ничего не понятно. Но я назову все переменные "говорящими" для меня названиями и за пару дней осилю.
Насчёт PoSh давно уже думаю но нет у меня пока условий дотошно учиться. Увы.

alpap
06-02-2018, 16:07
правда ничего не понятно »
принцип такой:
- вашу строку бьем по пробелу и в файл
- даем номера строкам
- выбираем номера строк с нужным тегом
- забираем строку с номером между найденных номеров выше и помещаем в переменную
ничего сложного, но букафф много :)

alpap
06-02-2018, 16:42
конкретно для вашего случая (в смысле поиск слова в предложении между двумя одинаковыми тегами) и без временного файла
(можно и еще короче, но пойдет и так, так понятнее, хотя смотря для кого)

@echo off
set "s=fast slow error password error garbage test text blabla"
set "teg=error"

setlocal enabledelayedexpansion
for %%a in (%s%) do set /a n+=1& set $_!n!=%%a
for /f "tokens=2 delims=_=" %%a in ('set $_^|find "%teg%"') do set /a sn=%%a-1
for /f "tokens=2 delims==" %%a in ('set $_%sn%') do set "var=%%a"
echo %var%
endlocal
pause

megaloman
06-02-2018, 17:20
вашу строку бьем по пробелу и в файл »Без файла. Оформил в виде процедуры. Избежал setlocal enabledelayedexpansion
В пароле не должно быть пробелов @Echo Off
cls

Set "Str=fast slow errOr password Error garbage test text blabla"
Set "Teg=error"

Call :Password "%Str%" "Pass"
Echo "%Pass%"

pause
GoTo :Eof

:Password
Set /A nTeg=0
:Begin
Set /A nTeg+=1
FOR /F "tokens=%nTeg% delims= " %%i IN ("%Str%") DO If /I %Teg%==%%i GoTo :Cont
GoTo :Begin
:Cont
Set /A nTeg+=1
FOR /F "tokens=%nTeg% delims= " %%i IN ("%Str%") DO Set "%~2=%%i"
GoTo :Eof

alpap
06-02-2018, 17:28
вот короче
вторичным тегом выступает = , можно назначить свой, если такой символ будет неуместен по тексту (в смысле присутствует уже)

@echo off
set "s=fast slow error password error garbage test text blabla"
set "teg=error"

cmd /v/c for %%v in ("!s: %teg% ==!") do for /f "tokens=2 delims==" %%a in ("%%~v") do echo %%a
pause

Patroklos
07-02-2018, 09:45
Круть! Спасибо. Чувствую я так и профессором "батаники" стану.
Я плашку решено пока не буду ставить так как мне возможно понадобятся подсказки.
Поставлю чуть позже. Спасибо.

megaloman
07-02-2018, 11:54
alpap, Краткость, несомненно, сестра таланта :) Но если текст будет вида "error password error garbage test text blabla" либо "fast slow error password error" Ваш батник отработает неверно. @Echo Off
cls

Set "Str=fast slow error password error garbage test text blabla"

Call :Password "%Str%" "error" "Pass"

Echo "%Pass%"
Pause
GoTo :Eof

:Password
SetLocal
Set "Dlm=ё"
Set "Str=a %~1 a" &Set "Teg= %~2 "
Call Set "Str=%%Str:%Teg%=%Dlm%%%"
EndLocal &FOR /F "tokens=2,3 delims=%Dlm%" %%i IN ("%Str%") DO If Not "%%j"=="" (Set "%~3=%%i") Else (Set "%~3=")
GoTo :Eof

В качестве вспомогательного разделителя я здесь указал ё, естественно, можно указать любой допустимый.
Set "Dlm=ё"
Однако, реально я тестировал батник с символом, который на клавиатуре пользователь, не обременённый излишними знаниями, не введёт. Например, символ ASCII с десятичным кодом 177. Я не смог разместить на форуме батник с этим символом (ломается весь текст сообщения), поэтому вынужденно указал ё.
Опять же, имхо выделение пароля - не основная цель в неизвестном нам батнике, поэтому я это оформил в виде процедуры, чтобы не загромождать основной текст кодаЧтобы вставить в текст символ ASCII с определённым десятичным кодом, надо на цифровой клавиатуре, удерживая клавишу Alt, набрать нужный код

alpap
07-02-2018, 17:42
Но если текст будет ...»
естественно

Patroklos
08-02-2018, 18:39
Здравствуйте ещё раз. Я посидел над вашими решениями, понял принципы и способы реализации и наконец то сдвинулся с места.
Спасибо вам большое. Теперь у меня очередная "глупая" проблема: я ищу строки в текстовом файле и в них ищу пароль.
Проблема что в файле может быть несколько паролей из которых мне нужен только первый. А он перезаписывается.
Существует ли какой либо способ выйти из FOR после того как результат получен? Как нибудь так?
for /f "tokens=2 delims=###" %%c in ("data.txt") do (
set var=%%c
if defined var ( Пока пока скрипт! )
проблема что у меня for-ы вложены и в результате ерунда.
Как прекратить FOR когда var дефайнет?

megaloman
08-02-2018, 22:01
@Echo Off
cls
Set "FileIn=Z:\Box_In\У попа была собака.txt"

Call :Password "%FileIn%" "error" "Pass"
Echo "%Pass%"

Pause
GoTo :Eof

:Password
FOR /F "usebackq delims=" %%s IN (%1) DO Call :PassIn "%%s" %2 %3 &&GoTo :Eof
GoTo :Eof
:PassIn
SetLocal
Set "Dlm=▒"
Set "Str=a %~1 a" &Set "Teg= %~2 "
Call Set "Str=%%Str:%Teg%=%Dlm%%%"
FOR /F "tokens=2,3 delims=%Dlm%" %%i IN ("%Str%") DO If Not "%%j"=="" (EndLocal &Set "%~3=%%i" &Exit /B 0)
EndLocal &(Set "%~3=" &Exit /B 1) В качестве вспомогательного разделителя я здесь указал символ ▒
то есть символ ASCII с десятичным кодом 177.
Set "Dlm=▒"
естественно, можно указать любой допустимый, но гарантированно отсутствующий в тексте

Patroklos
08-02-2018, 22:27
И снова спасибо! Выручаете. Сейчас буду разбираться что да как.

megaloman
08-02-2018, 22:27
delims=###» ИМХО, разделитель - это один символ. И повторять его три раза не имеет смысла. Можно указать набор символов, например, три разных символа, если нужно.
Кстати, в посте #9 я накосячил: строка вида
fast slow error password garbage test text blabla
обрабатывалась неверно. Исправил.

Patroklos
09-02-2018, 22:18
Спасибо большое. С ваше помощью я понял как надо всё делать и всё таки собрал своего Франкинштейна.
Теперь у меня проблемы с кодировками. Я работаю с информацией скачиваемой и загружаемой с/на сайт
и пока всё на английском всё отлично а с русским местами проблемы. Боюсь опять придётся просить помощи.
Насчёт разделителя вы правы одного уникального символа достаточно. И работать с ним гораздо легче.
Ещё раз спасибо.

megaloman
09-02-2018, 22:43
Patroklos, @Echo Off
cls
chcp 1251 >nul
Set "FileIn=Z:\Box_In\У попа была собака.txt"

Call :Password "%FileIn%" "ошибка" "Pass"

Echo "%Pass%"
Pause
GoTo :Eof

:Password
FOR /F "usebackq delims=" %%s IN (%1) DO Call :PassIn "%%s" %2 %3 &&GoTo :Eof
GoTo :Eof

:PassIn
SetLocal
Set "Dlm=¤"
Set "Str=a %~1 a" &Set "Teg= %~2 "
Call Set "Str=%%Str:%Teg%=%Dlm%%%"
FOR /F "tokens=2,3 delims=%Dlm%" %%i IN ("%Str%") DO If Not "%%j"=="" (EndLocal &Set "%~3=%%i" &Exit /B 0)
EndLocal &(Set "%~3=" &Exit /B 1)Надо только вспомогательный символ-разделитель подрбрать.

Patroklos
09-02-2018, 23:49
Проблема не в той части где ваш код. Там всё отлично.
Я беру полученную переменную, подставляю её в json строку и при помощи curl передаю её на сервер.
и тут возникает проблема. Пока всё на английском всё супер. С русским проблемы.
Если я определяю переменную в ручную в файле
set var=русский текст
и кодировка 1251 то всё работает. Если любой другой способ ( например set /p var=<data.log )
та работать отказывается. Сервер ругается на какой то нуль байт в кодировке.
Я уже в ручную все возможные кодировки перебрал. И chcp и кодировки файла и в curl настройки.
И увы пока глухо. Назавтра свежим взглядом взгляну может придумаю чего.

alpap
10-02-2018, 01:50
Patroklos
не надо перебирать кодировки, вы хозяин положения и доступ есть ко всем файлам. Сохраняйте все (совсем все и текстовые и bat) в кодировке 866, проблем поубавится, особенно если замените топорный виндовый блокнот на что-то стОящее.

Patroklos
10-02-2018, 17:58
Сохраняйте все (совсем все и текстовые и bat) в кодировке 866, проблем поубавится »
Дело в том что json в принципе работает в utf-8 и с любой другой кодировкой не дружит.
а потрогать файл можно, на который сервер ругается?
Можно сделать задачу в vbs? Или часть задачи в vbs/js ?
»
Я пока активно гуглю пытаясь найти решение но похоже мало кто использует вин смд для работы с json.
Сам файл прост как гвоздь проблема именно с кодировками.
chcp 1251
..\bin\curl.exe --request PATCH ^
https://site.ru/api/path/pid/ ^
--header "Content-Type: application/json; charset=UTF-8" ^
--header "Accept: application/json" ^
-d "{\"data\": {\"pass\": \"%var%\"}}" >.\json\Editet.json
тут просто негде напортачить.
Всем спасибо большое за помощь. Я многому научился на ваших примерах.
Ставлю теме решено так как извлекать инфу по делиму я с вашей помощью научился.




© OSzone.net 2001-2012