Компьютерный форум 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=333003)

Patroklos 05-02-2018 17:36 2795983

Выделить часть строки и отправить в переменную
 
Здравствуйте, подскажите какие способы есть отправить в переменную часть строки?
Например строка
Код:

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

alpap 06-02-2018 12:13 2796186

допустим так, хоть и не коротко:
Код:

@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 2796197

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

alpap 06-02-2018 16:07 2796243

Цитата:

Цитата Patroklos
правда ничего не понятно »

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

alpap 06-02-2018 16:42 2796251

конкретно для вашего случая (в смысле поиск слова в предложении между двумя одинаковыми тегами) и без временного файла
(можно и еще короче, но пойдет и так, так понятнее, хотя смотря для кого)
Код:

@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 2796262

Цитата:

Цитата alpap
вашу строку бьем по пробелу и в файл »

Без файла. Оформил в виде процедуры. Избежал 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 2796264

вот короче
вторичным тегом выступает = , можно назначить свой, если такой символ будет неуместен по тексту (в смысле присутствует уже)
Код:

@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 2796399

Круть! Спасибо. Чувствую я так и профессором "батаники" стану.
Я плашку решено пока не буду ставить так как мне возможно понадобятся подсказки.
Поставлю чуть позже. Спасибо.

megaloman 07-02-2018 11:54 2796460

alpap, Краткость, несомненно, сестра таланта :) Но если текст будет вида "error password error garbage test text blabla" либо "fast slow error password error" Ваш батник отработает неверно.
Предлагаю длиннее, но с учетом этих имхо возможных случаев. Как и у Вас, батник работает в предположении, что между error и password не более одного пробела
Код:

@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 2796538

Цитата:

Цитата megaloman
Но если текст будет ...»

естественно

Patroklos 08-02-2018 18:39 2796804

Здравствуйте ещё раз. Я посидел над вашими решениями, понял принципы и способы реализации и наконец то сдвинулся с места.
Спасибо вам большое. Теперь у меня очередная "глупая" проблема: я ищу строки в текстовом файле и в них ищу пароль.
Проблема что в файле может быть несколько паролей из которых мне нужен только первый. А он перезаписывается.
Существует ли какой либо способ выйти из 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 2796855

я ищу строки в текстовом файле и в них ищу пароль между двумя определёнными одинаковыми словами.
Код:

@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 2796867

И снова спасибо! Выручаете. Сейчас буду разбираться что да как.

megaloman 08-02-2018 22:27 2796868

Цитата:

Цитата Patroklos
delims=###»

ИМХО, разделитель - это один символ. И повторять его три раза не имеет смысла. Можно указать набор символов, например, три разных символа, если нужно.

Кстати, в посте #9 я накосячил: строка вида
fast slow error password garbage test text blabla
обрабатывалась неверно. Исправил.

Patroklos 09-02-2018 22:18 2797073

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

megaloman 09-02-2018 22:43 2797078

Patroklos,
Если текст в 1251 кодировке и батник сохранить в 1251 кодировке, вроде бы так работает
Код:

@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 2797087

Проблема не в той части где ваш код. Там всё отлично.
Я беру полученную переменную, подставляю её в json строку и при помощи curl передаю её на сервер.
и тут возникает проблема. Пока всё на английском всё супер. С русским проблемы.
Если я определяю переменную в ручную в файле
Код:

set var=русский текст
и кодировка 1251 то всё работает. Если любой другой способ ( например set /p var=<data.log )
та работать отказывается. Сервер ругается на какой то нуль байт в кодировке.
Я уже в ручную все возможные кодировки перебрал. И chcp и кодировки файла и в curl настройки.
И увы пока глухо. Назавтра свежим взглядом взгляну может придумаю чего.

alpap 10-02-2018 01:50 2797105

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

Patroklos 10-02-2018 17:58 2797172

Цитата:

Цитата alpap
Сохраняйте все (совсем все и текстовые и bat) в кодировке 866, проблем поубавится »

Дело в том что json в принципе работает в utf-8 и с любой другой кодировкой не дружит.
Цитата:

Цитата megaloman
а потрогать файл можно, на который сервер ругается?
Можно сделать задачу в 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

тут просто негде напортачить.
Всем спасибо большое за помощь. Я многому научился на ваших примерах.
Ставлю теме решено так как извлекать инфу по делиму я с вашей помощью научился.


Время: 04:07.

Время: 04:07.
© OSzone.net 2001-