How to set variable using substring in batch code (Windows CMD)

Asked

Viewed 516 times

0

Talk to you guys, I am trying to generate a code seeking part of the service name in Windows to set in a variable (ORACLE_SID). I need to search the service Oracleservice. Next to the name has the name of the base. I need to get only the name of the base.

Ex.:

OracleServiceXXX
OracleServiceYYY
OracleServiceZZZ

I tried through the following LOOP:

for /f "tokens=2" %s in ('sc query state^= all ^| find "OracleService"')

I tried to set the value with substring to the ORACLE_SID variable via do set ORACLE_SID=%s:~13,20% , but returns this way:

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%

How do I set ORACLE_SID only with the final part of the service name, and how do I return it only once, without repeating the same ORACLE_SID value earlier?

Ex what I need:

set ORACLE_SID=XXX
set ORACLE_SID=YYY
set ORACLE_SID=ZZZ

Thanks!!!

1 answer

0

*/ EDIT

How do I set ORACLE_SID only with the final part of the service name, and how do I return it only once, without repeating the same ORACLE_SID value earlier?

- Note: The answer also covers other points addressed in another author’s post (already duly deleted by moderation), where in this, have a deviation from the original question the origin of the 3rd item listed below/answered

  • Get your substring in: first occurrence

  • Get your substring in: last occurrence

  • Get your substring of: each occurrence



  • Get your substring of each occurrence      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
       echo\Servico %_svrc% não se encontra em execução
     
    ) else (
     
      for /L %%i in (1 1 !_cnt!)do call echo\Nome da Base: !_base_%%~i!

    )     

timeout.exe -1

popd
endlocal
  • Compact and unused version "didactic layout" in the code:
@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=& echo\Serviço !_svrc! não foi encontrado em execução^!! 
)else for /L %%i in (1 1 !_cnt!)do set "_b=00%%~i" && call echo\Base "!_b:~-2!": !_base_%%~i! 

timeout.exe /t -1 & popd | endlocal & goto=:EOF 

  • Note: 1 For testing purposes I am replacing OracleService for Windows, since I do not have this service in multiple occurrences being executed.

  • 1. Without any manipulation by a loop for for the command:
sc query | find "_NAME:" | find /i "windows"
  • The output returns this way:
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
  • 2. Using a loop for /f and counting occurrences to concatenate its variable with the Udo of a counter (set /a "_cnt+=1+0"), implemented in a way that allows saving each occurrence in a separate variable:
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
  • 3. The above actions will be (applied) in the processing that returns from the loop For /F by command sc query | find "_NAME:" | find /i "%_svrc%" (item 1.), adding use of a set _var=substring(%_var:removeSstring=%) to treat in the variable the value of the strings you want to remove/stay. In your case, remove everything that comes before Oracleservice and take everything that comes after, would:
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
  • 4. Using/applying for example in one of the names in the listing of Windows services, such as the Windows Update (see Note: 1), would result in 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"
  • 5. The same accountant !_cnt! incremented in the looping For /F, you can use to Ober the list of occurrences setadas/definas, just make use of a loop For /L, within a predefined numerical range for start value **1, jump value **1, and end/end value !_cnt!, so that all occurrences/strings will be accessed in the same way they were defined, using concatenation:
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
  • 6. For classification and comparison purposes only in test runs, a concatenation of two zeros added when defining _b=%%i (set _b=00%%i), and in the listing it was possible to use 02 digits, when relating the output of the services found in their respective variables accessed by For /L, getting in the list the bases with this layout Base 01, instead of Base 01:

)else for /L %%i in (1 1 !_cnt!)do set "_b=00%%~i" && call echo\Base "!_b:~-2!": !_base_%%~i! 
  • Remembering the replacement of OracleService for Windows (vine Note: 1), and compare the Stings in the original loop output and the changes made with set string=substring:
  • Original Output
    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
  • Output Variable Listings ! _base_1! - ! _base_20!
    for /L %%i in (1 1 !_cnt!)do set "_b=00%%~i" && call echo\Base "!_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 /*



  • Get your substring in first occurrence of your 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%
echo\Nome da Base: %_3d%
  • Compact and unused version "didactic layout" in the code:
@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% & echo\Nome da Base: %_3d% & endlocal & goto :EOF
  • To get in the service name the base name and catch the last 3 characters
    already saving that string in a variable, only use :~-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
  • To return only to first occurrence in looping, create a leak using a
    :label to get out of this looping in 1ª execução already saving your 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

Note: 3 |find/i 'OracleService' ⁄⁄ Use 'case-insensitive == /i' no seu 'find'

Only use the literal name when you are sure that the string has only occurrences with this layout, otherwise consider that string may differ (containing uppercase/lowercase only or other unforeseeable variations) from the layout currently in presumed use in its code



  • Get your substring in last occurrence of your 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 (
                
                 echo\Servico OracleService nao foi encontrado em execucao
                 timeout /t -1
                 
                 goto :EOF
                    
            )
        )
    )
    
echo\%_var% && echo\%_3d% & endlocal  & goto :EOF
  • Compact version without the use of "didactic layout" in the code:
@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 echo\Servico OracleService nao encontrado em execucao^^!! & %__APPDIR__%timeout.exe -1 & endlocal & goto :EOF
    
echo\%_var% && echo\Nome da base: %_3d% & endlocal & goto :EOF


  • To obtain the last occurrence it will be necessary to count and operate on total (ocorrências) -1, where what will matter is:
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

Note: 4 You probably don’t need anything in the additional information from state^=all.

for /f %%i in ('sc query state^=all^| find /i "OracleService" ^| find /v /c ""') do ... 



Browser other questions tagged

You are not signed in. Login or sign up in order to post.