Stack Overflow em Português Asked by grmf on November 8, 2021
Fala galera,
To tentando gerar um código buscando parte do nome do serviço no Windows para setar em uma variável (ORACLE_SID).
Preciso fazer uma busca no serviço OracleService. Junto do nome tem o nome da base. Preciso pegar somente o nome da base.
Ex.:
OracleServiceXXX
OracleServiceYYY
OracleServiceZZZ
Tentei através do seguinte LOOP:
for /f "tokens=2" %s in ('sc query state^= all ^| find "OracleService"')
Tentei setar o valor com substring para a variável ORACLE_SID através de do set ORACLE_SID=%s:~13,20%
, mas retorna desta forma:
set ORACLE_SID=OracleServiceXXX:~13,20%
set ORACLE_SID=OracleServiceXXX:~13,20%
set ORACLE_SID=OracleServiceYYY:~13,20%
set ORACLE_SID=OracleServiceYYY:~13,20%
set ORACLE_SID=OracleServiceZZZ:~13,20%
set ORACLE_SID=OracleServiceZZZ:~13,20%
Como faço para setar ORACLE_SID somente com a parte final do nome do serviço, e como faço pra ele retornar somente uma vez, sem repetir o mesmo valor ORACLE_SID anterior?
Ex do que preciso:
set ORACLE_SID=XXX
set ORACLE_SID=YYY
set ORACLE_SID=ZZZ
Valeu!!!
*/ EDIT
Como faço para setar ORACLE_SID somente com a parte final do nome do serviço, e como faço pra ele retornar somente uma vez, sem repetir o mesmo valor ORACLE_SID anterior?
- Nota: A resposta abrange também outros pontos abordados em uma outra postagem do autor (já devidamente apagada pela moderação), onde nesta, têm-se um desvio do questionamento original a origem do 3º item abaixo listado/respondido
Obtenha sua substring
na: 1ª ocorrência
Obtenha sua substring
na: última ocorrência
Obtenha sua substring
de: cada ocorrência
substring
de cada ocorrência ⁄ ⁄ edit@echo off
Setlocal EnableDelayedExpansion
pushd %__APPDIR__% && set "_svrc=OracleService"
for /f "tokens=*" %%s in ('sc query ^| find "_NAME:" ^| find /i "%_svrc%"')do (
set /a "_cnt+=1+0" && set "_str=%%~s" && call set "_base_!_cnt!=!_str:*%_svrc%=!"
)
if not defined _cnt (
>nul chcp 65001
echoServico %_svrc% não se encontra em execução
) else (
for /L %%i in (1 1 !_cnt!)do call echoNome da Base: !_base_%%~i!
)
timeout.exe -1
popd
endlocal
- Versão compacta e sem uso de "layout didático" no código:
@echo off && Setlocal EnableDelayedExpansion
set "_svrc=OracleService" & >nul chcp 65001 | pushd %__APPDIR__%
for /f tokens^=* %%s in ('sc.exe query^|find "_NAME:"^|find/i "%_svrc%"
')do set/a "_cnt+=1+0" && set "_str=%%~s" && call set "_base_!_cnt!=!_str:*%_svrc%=!"
if not defined _cnt (<con: echo=& echoServiço !_svrc! não foi encontrado em execução^!!
)else for /L %%i in (1 1 !_cnt!)do set "_b=00%%~i" && call echoBase "!_b:~-2!": !_base_%%~i!
timeout.exe /t -1 & popd | endlocal & goto=:EOF
OracleService
por Windows
, já que não tenho esse serviço em múltiplas ocorrências sendo executado.for
para o comando:sc query | find "_NAME:" | find /i "windows"
DISPLAY_NAME: Windows Audio Endpoint Builder
DISPLAY_NAME: Windows Audio
DISPLAY_NAME: Windows Event Log
DISPLAY_NAME: Windows Font Cache Service
DISPLAY_NAME: Windows Presentation Foundation Font Cache 3.0.0.0
DISPLAY_NAME: Windows Phone IP over USB Transport (IpOverUsbSvc)
DISPLAY_NAME: Windows License Manager Service
DISPLAY_NAME: Windows Defender Firewall
DISPLAY_NAME: Windows Security Service
DISPLAY_NAME: Windows Image Acquisition (WIA)
DISPLAY_NAME: Windows Biometric Service
DISPLAY_NAME: Windows Connection Manager
DISPLAY_NAME: Windows Defender Antivirus Network Inspection Service
DISPLAY_NAME: Windows Defender Antivirus Service
DISPLAY_NAME: Windows Management Instrumentation
DISPLAY_NAME: Windows Push Notifications System Service
DISPLAY_NAME: Windows Search
DISPLAY_NAME: Windows Push Notifications User Service_6a4f9
for /f
e contando as ocorrências para concatenar sua variável com o udo de um contador (set /a "_cnt+=1+0"
), implementado de forma que permita salvar cada ocorrência em uma variável separadamente:1º loop:
set _seu_contador=contador + 1 ⁄⁄ set /a _cnt=1+0 == set /a _cnt+=1+0
set _var_contador=1ª ocorrência ⁄⁄ set /a _var_1=ocorrência == set_var_!_cnt!=1ª ocorrência
2º loop:
set _seu_contador=contador + 1 ⁄⁄ set /a _cnt=1+1+0 == set /a _cnt+=1+0
set _var_contador=2ª ocorrência ⁄⁄ set /a _var_2=ocorrência == set_var_!_cnt!=2ª ocorrência
3º loop:
set _seu_contador=contador + 1 ⁄⁄ set /a _cnt=2+1+0 == set /a _cnt+=1+0
set _var_contador=3ª ocorrência ⁄⁄ set /a _var_3=ocorrência == set_var_!_cnt!=3ª ocorrência
⁄⁄ Obs.: Como a variável _cnt não foi definida antes
⁄⁄ do 1º loop/uso, use '+0': set /a _cnt+=1+0
For /F
pelo comando sc query | find "_NAME:" | find /i "%_svrc%"
(item 1.), adionando use um set _var=substring(%_var:removeSstring=%)
para tratar na variavel o valor das strings que deseja remover/ficar. No seu caso caso, remover tudo que vem antes de OracleService e ficar com tudo que venha depois, seria:set variavel=Remover Qualquer Strings Antes De OracleService Ficando Qualquer Strings Depois
set variavel=Remover Qualquer Strings Antes De OracleService
set variavel=%variavel:*OracleService=%
set variavel=o seu valor mas tudo ("*") antes de 'OracleService' substituir ("=") por nada ("=%")
set variavel=%variavel:*OracleService=%Ficando Qualquer Strings Depois
Windows Update
(veja Obs.: 1), resultaria em Update
:set variavel=%%~s
set variavel=Windows Update
set variavel=%variavel:*Windows`espaço!`=%
set variavel=%variavel:*Windows =%
set variavel=%variavel:*Windows Update
set variavel=Update
set "_svrc=Windows"
....
set "_str=Windows Update"
set "_base_!_cnt!=!_str:*Windows %=!" ⁄⁄ o mesmo que: set "_base_!_cnt!=Update"
set "_str=Windows Update"
set "_base_!_cnt!=!_str:*%_svrc%=!" ⁄⁄ o mesmo que: set "_base_!_cnt!=*Windows Update"
!_cnt!
incrementado no looping For /F
, você pode usar para ober a listagem das ocorrências setadas/definas, basta fazer uso de um loop For /L
, que dentro de um intervalo númerico pré definido para valor de início **1
, valor de salto **1
, e o valor de fim/final !_cnt!
, de forma que todas as ocorrências/strings serão acessadas da mesma maneira com que foram definidas, usando concatenação:For /L %%i in (1 1 !_cnt!)do... !_base_%%i!
⁄⁄ Existindo 3 ocorrências, o valor de !_cnt! será igual a 3, e loop
⁄⁄ ficaria entre 1 e 3, pulando de 1 em 1: For /L %%i in (1 1 3,)do...
For /L %%i in (1 1 !_cnt!)do... !_base_1! string na 1ª ocorrência/variável ⁄⁄ %%i == 1
do... !_base_2! string na 2ª ocorrência/variável ⁄⁄ %%i == 2
do... !_base_3! string na 3ª ocorrência/variável ⁄⁄ %%i == 3
For /L %%i in (1 1 !_cnt!)do... !_base_%%i! string na 1ª ocorrência/variável ⁄⁄ %%i == 1
do... !_base_%%i! string na 2ª ocorrência/variável ⁄⁄ %%i == 2
do... !_base_%%i! string na 3ª ocorrência/variável ⁄⁄ %%i == 3
_b=%%i
(set _b=00%%i
), e na listagem fosse possível o uso de 02
dígitos, ao relacionar a saída dos serviços encontrados nas suas respectivas variáveis acessados pelo For /L
, obtendo na listagem as bases com esse layout Base 01
, ao invés de Base 01
:
)else for /L %%i in (1 1 !_cnt!)do set "_b=00%%~i" && call echoBase "!_b:~-2!": !_base_%%~i!
OracleService
por Windows
(vide Obs.: 1), e compare as stings na saída original do loop e nas alterações feitas com set string=substring
:sc query | find "_NAME:" | find /i "windows"
DISPLAY_NAME: Windows Audio Endpoint Builder
DISPLAY_NAME: Windows Audio
DISPLAY_NAME: Windows Event Log
DISPLAY_NAME: Windows Font Cache Service
DISPLAY_NAME: Windows Presentation Foundation Font Cache 3.0.0.0
DISPLAY_NAME: Windows Phone IP over USB Transport (IpOverUsbSvc)
DISPLAY_NAME: Windows License Manager Service
DISPLAY_NAME: Windows Defender Firewall
DISPLAY_NAME: Windows Security Service
DISPLAY_NAME: Windows Image Acquisition (WIA)
DISPLAY_NAME: Windows Biometric Service
DISPLAY_NAME: Windows Connection Manager
DISPLAY_NAME: Windows Defender Antivirus Network Inspection Service
DISPLAY_NAME: Windows Defender Antivirus Service
DISPLAY_NAME: Windows Management Instrumentation
DISPLAY_NAME: Windows Push Notifications System Service
DISPLAY_NAME: Windows Search
DISPLAY_NAME: Windows Push Notifications User Service_6a4f9
for /L %%i in (1 1 !_cnt!)do set "_b=00%%~i" && call echoBase "!_b:~-2!": !_base_%%~i!
Base 01: Audio Endpoint Builder
Base 02: Audio
Base 03: Event Log
Base 04: Font Cache Service
Base 05: Presentation Foundation Font Cache 3.0.0.0
Base 06: Phone IP over USB Transport (IpOverUsbSvc)
Base 07: License Manager Service
Base 08: Defender Firewall
Base 09: Security Service
Base 10: Image Acquisition (WIA)
Base 11: Biometric Service
Base 12: Connection Manager
Base 13: Connect Now - Config Registrar
Base 14: Defender Antivirus Network Inspection Service
Base 15: Defender Antivirus Service
Base 16: Management Instrumentation
Base 17: Push Notifications System Service
Base 18: Search
Base 19: Update
Base 20: Push Notifications User Service_6a4f9
EDIT /*
substring
na 1ª ocorrência do seu looping:@echo off
for /f "tokens=* delims= " %%s in ('sc query ^| find /i "OracleService"') do (
set "_var=%%~s"
set "_3d=%_var:~-3%"
goto :LABEL
)
:LABEL
echo%_var%
echoNome da Base: %_3d%
- Versão compacta e sem uso de "layout didático" no código:
@echo off && setLocal EnableDelayedExpansion
for /f tokens^=* %%s in ('
%__APPDIR__%sc.exe query^|find/i "OracleService"
')do set "_var=%%~s" && call set "_3d=!_var:~-3!" & goto :^v
:^v
echo%_var% & echoNome da Base: %_3d% & endlocal & goto :EOF
string
numa variável, apenas utilize :~-3
set !"_var=%%~s!"
set !"_3d=%_var:~-3%!"
rem :: ou...
')do set "_var=%%~s" & call set "_3d=!_var:~-3!" ⁄⁄ para uso na mesma linha⁄layout compacto
:label
para sair desse looping na 1ª execução
já salvando sua substring
set !"_var=%%~s!"
set !"_3d=%_var:~-3%!"
goto :LABEL
rem :: ou...
')do set "_var=%%~s" & call set "_3d=!_var:~-3
set "_var=%%~s" & call set "_3d=!_var:~-3!" & goto :label ⁄⁄ para uso na mesma linha⁄layout compacto
Obs.: 3 |find/i 'OracleService' ⁄⁄ Use 'case-insensitive == /i' no seu 'find'
Só utilize o nome literal quando estiver certeza que a string tem somente ocorrências com esse layout, caso contrário, considere que string
possa divergir (contendo somente maiúsculas/minúsculas ou ainda outras variações imprevisíveis) do layout atualmente em uso presumido no seu código bat
substring
na última ocorrência do seu looping:@echo off && Setlocal EnableDelayedExpansion
for /f %%i in ('sc query ^| find /i "OracleService" ^| find /v /c ""') do (
if /i %%~i gtr 2 (
call set /a "_x=%%i-1"
for /f "tokens=* delims= " %%s in ('sc query ^| find /i "OracleService" ^| more /s +!_x!') do (
set "_var=%%~s"
call set "_3d=!_var:~-3!"
)
) else if %%~i equ 1 (
for /f tokens^=* %%s in ('sc query ^| find /i "OracleService"') do (
set "_var=%%~s"
call set "_3d=!_var:~-3!"
)
) else (
echoServico OracleService nao foi encontrado em execucao
timeout /t -1
goto :EOF
)
)
)
echo%_var% && echo%_3d% & endlocal & goto :EOF
- Versão compacta e sem o uso de "layout didático" no código:
@echo off && setLocal EnableDelayedExpansion
for /f %%i in ('%__APPDIR__%sc.exe query^|find/i "OracleService"^|find/v /c ""')do if %%~i gtr 2 (
call set /a "_x=%%i-1" && for /f tokens^=* %%s in ('%__APPDIR__%sc.exe query^|find/i "OracleService"^|%__APPDIR__%more.com /s +!_x!
')do set "_var=%%~s" && call set "_3d=!_var:~-3!" ) else if %%~i equ 1 (for /f tokens^=* %%s in ('%__APPDIR__%sc.exe query^|find/i "OracleService"
')do set "_var=%%~s" && call set "_3d=!_var:~-3!" ) else echoServico OracleService nao encontrado em execucao^^!! & %__APPDIR__%timeout.exe -1 & endlocal & goto :EOF
echo%_var% && echoNome da base: %_3d% & endlocal & goto :EOF
total (ocorrências) -1
, onde o que vai importar saber é:Se Total ≥ 2 ⁄⁄ pular na listagem Total - 1
Se Total = 1 ⁄⁄ apenas usar mais ações não são necessárias
Se Total = 0 ⁄⁄ informar serviço não encontrado
Obs.: 4 Provavelmente não precise de nada nas informações adicionais do state^=all
.
for /f %%i in ('sc query state^=all^| find /i "OracleService" ^| find /v /c ""') do ...
Algumas leituras adicionais in //English
[√] Sc
[√] Set
[√] CMD /?
[√] Setlocal
[√] For Loop
[√] For /F Loop
Answered by Io-ol on November 8, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP