How to get all characters after a substring

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Furplado
Posts: 12
Joined: 13 Feb 2021 10:18

How to get all characters after a substring

#1 Post by Furplado » 14 Feb 2021 03:09

In a cmd-window (Windows 7) I make this:

Code: Select all

C:\Users\D>set test=aaaIIIbbb

C:\Users\D>for /f "tokens=III delims==" %%a in ("%test%") do (  echo %%a  ) 
"%%a" cannot be processed syntactically at this point.
What's wrong here? My expectation was, that I will get "bbb" as output.


Would appreciate some help. Thank you.

aGerman
Expert
Posts: 4080
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to get all characters after a substring

#2 Post by aGerman » 14 Feb 2021 09:57

Furplado wrote:
14 Feb 2021 03:09
What's wrong here?
Almost everything.

First of all, in a cmd prompt the FOR variables are preceded by one percent sign (rather than two, which would be the syntax in a batch script).
I strongly advise you to carefully read the help of FOR (run FOR /? in a cmd prompt). Tokens is a list of numbers which specifies the substrings you want to assign to the FOR variables. Delims is a set of separator characters. Each of these characters is used as separator rather than the entire string. So, something like delims=III means I or I or I which eventually makes no sense. I used $ to replace the III in the variable value, and defined $ as delimiter. If $ is something which may appear in your real string, then choose another character.

Code: Select all

C:\Users\steffen>set test=aaaIIIbbb

C:\Users\steffen>for /f "tokens=2 delims=$" %a in ("%test:III=$%") do @echo %a
bbb

C:\Users\steffen>
Steffen

Furplado
Posts: 12
Joined: 13 Feb 2021 10:18

Re: How to get all characters after a substring

#3 Post by Furplado » 14 Feb 2021 10:33

Thank you @aGerman. Thanks to your help, the following works now:

What I have typed in my cmd-window:

Code: Select all

C:\Users\D>FOR /F "tokens=* USEBACKQ" %g IN (`REG QUERY HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice`) do (SET "Registry1=%g") && for /f "tokens=2 delims=$" %a in ("%Registry1:Word=$%") do @echo %a
The output:

Code: Select all

C:\Users\D>(SET "Registry1=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" )  && for /F "tokens=2 delims=$" %a in ("Progid    REG_SZ    $.Document.12") do @echo %a
.Document.12

C:\Users\D>(SET "Registry1=Progid    REG_SZ    Word.Document.12" )  && for /F "tokens=2 delims=$" %a in ("Progid    REG_SZ    $.Document.12") do @echo %a
.Document.12

C:\Users\D>
This above is able to bring ...

Code: Select all

"Progid    REG_SZ    Word.Document.12"    
... in the first step into the variable "Registry1".
After in step 2, it extracts ".Documents.12" and shows it.

I like it.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

But I need ".Documents.12" also in a variable. For example in "Registry1Ext"
How can I bring ".Documents.12" in a variable?
I have tried this, but it has not worked:

Code: Select all

C:\Users\D>set Registry1Ext=( for /f "tokens=2 delims=$" %a in ("%Registry1:Word=$%") do @echo %a )
Why do I need it in the variable "Registry1Ext"?
Answer: Because later I would need "Registry1Ext" for the following command:

Code: Select all

vboxcontrol guestproperty set /testproprties/myprop %Registry1Ext%
Then It''s done.

(But I need all this in one line. For example by using "&&".)

aGerman
Expert
Posts: 4080
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to get all characters after a substring

#4 Post by aGerman » 14 Feb 2021 10:57

Furplado wrote:
14 Feb 2021 10:33
(But I need all this in one line.)
Whould have been much easier to write it in a script rather than having everything in one line for the prompt.
Nevermind. You can use the dot as delimiter instead of replacing string "Word".
Untested:

Code: Select all

for /f "tokens=2*" %a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"') do @for /f "tokens=1* delims=." %c in ("%b") do @set "Registry1Ext=.%d"
... or even ...

Code: Select all

for /f "tokens=2*" %a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"') do @for /f "tokens=1* delims=." %c in ("%b") do @vboxcontrol guestproperty set /testproprties/myprop .%d
Steffen

Furplado
Posts: 12
Joined: 13 Feb 2021 10:18

Re: How to get all characters after a substring

#5 Post by Furplado » 14 Feb 2021 13:08

Thank you. I have tried out the first example and it works.



aGerman wrote:
14 Feb 2021 10:57
You can use the dot as delimiter instead of replacing string "Word".
No, I need the version with the string "Word".

I have tried to change your first example to get the version with the string "Word":

Code: Select all

for /f "tokens=2*" %a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"') do @for /f "tokens=2 delims=$" %a in ("%Registry1:Word=$%") do @set "Registry1Ext=%a"
As I need the value of the variable "Registry1Ext" in my property "myproperty", I have added this piece of code with "&&" at the end:

Code: Select all

&& vboxcontrol guestproperty set /myproperties/myproperty %Registry1Ext%
So that the whole code looks now like this:

Code: Select all

for /f "tokens=2*" %a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"') do @for /f "tokens=2 delims=$" %a in ("%Registry1:Word=$%") do @set "Registry1Ext=%a" && D:\NT3x\vboxcontrol guestproperty set /myproperties/myproperty %Registry1Ext%
But this seems not to work as expected.
I have run the command first with ("%Registry1:Word=$%").
After again the same command but now with ("%Registry1:Wo=$%")
"Wo" instead of "Word".

Whereas the variable "Registry1Ext" has immediately the new content, it looks like the property "myproperty" is one step behind:

Code: Select all

C:\Users\D>for /f "tokens=2*" %a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows
\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"') do @for /f "to
kens=2 delims=$" %a in ("%Registry1:Word=$%") do @set "Registry1Ext=%a" && D:\NT
3x\vboxcontrol guestproperty set /myproperties/myproperty %Registry1Ext%
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6
.1.14
(C) 2008-2020 Oracle Corporation
All rights reserved.


C:\Users\D>echo %Registry1Ext%
.Document.12

C:\Users\D>vboxcontrol guestproperty get /myproperties/myproperty
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6
.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.

Value: .Document.12

C:\Users\D>for /f "tokens=2*" %a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows
\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"') do @for /f "to
kens=2 delims=$" %a in ("%Registry1:Wo=$%") do @set "Registry1Ext=%a" && D:\NT3x
\vboxcontrol guestproperty set /myproperties/myproperty %Registry1Ext%
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6
.1.14
(C) 2008-2020 Oracle Corporation
All rights reserved.


C:\Users\D>echo %Registry1Ext%
rd.Document.12

C:\Users\D>vboxcontrol guestproperty get /myproperties/myproperty
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6
.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.

Value: .Document.12

C:\Users\D>

(?)

aGerman
Expert
Posts: 4080
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to get all characters after a substring

#6 Post by aGerman » 14 Feb 2021 13:25

Don't get it, sorry. You told that my first example works. This is where I already used the dot as delimiter. It's just preceded to %d again as you can see in the code. So, in %d is only Document.12, however the set "Registry1Ext=.%d" yields .Document.12 in Registry1Ext.
Actually my second example should almost work out of the box since .%d is passed to vboxcontrol. Just add its path if necessary.
Do NOT work with additional variables like Registry1Ext here. It won't expand to the value which was previously updated in the same command line. This would require delayed variable expansion which makes things more complicated. Alternatively you can still use everything in a batch script where you wouldn't be facing this kind of issues.

Steffen

Eureka!
Posts: 123
Joined: 25 Jul 2019 18:25

Re: How to get all characters after a substring

#7 Post by Eureka! » 14 Feb 2021 14:15

This is quite chaotic, indeed.
What should variable Registry1Ext contain?
It looked like it should be .Document.12, but some time later you say:
Furplado wrote:
14 Feb 2021 13:08
No, I need the version with the string "Word".
Furplado wrote:
14 Feb 2021 13:08
Whereas the variable "Registry1Ext" has immediately the new content, it looks like the property "myproperty" is one step behind:
Take a look at DELAYEDEXPANSION ( SETLOCAL /? and SET /?).
That isn't possible on the command-line, so you have to use a workaround to cretae ' late expansion' That can be done using the CALL command.
You can also replace text up until a character/ word in one pass by using set OUt=%var:*word=%

So, if you want Registry1 variable to be .Document.12 you can do the following:
If not I would urgently advice you to start all over from the beginning, show the output of each individual command (I have no MS Word installed, for example) and be specific.

Code: Select all

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call set YOURVAR=%BUFFER:*Word=%
(Untested)

Furplado
Posts: 12
Joined: 13 Feb 2021 10:18

Re: How to get all characters after a substring

#8 Post by Furplado » 14 Feb 2021 16:51

aGerman wrote:
14 Feb 2021 13:25
Actually my second example should almost work out of the box ...
Unfortunately the second example from post <14 Feb 2021 17:57> seems not to work:

Code: Select all

C:\Users\D>for /f "tokens=2*" %a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"') do @for /f "to
kens=1* delims=." %c in ("%b") do @vboxcontrol guestproperty set /testproprties/myprop .%d
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.


C:\Users\D>vboxcontrol guestproperty get /myproperties/myproperty
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.

Value:
-> As you see, the value in myproperty is "", but should be .Document.12 .
Edit: I was wrong. This code works in principle.
To be more exactly: It only works one time after the boot of windows. When I repeat it with another <delims=>, in the same cmd-window, then the property "myproperty" remains unchanged. Also when I open another fresh cmd-windows, then the property "myproperty" remains unchanged.



Again:
What I want to have:
The entry form the registry what I am interested in is:

Code: Select all

C:\Users\D>reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"
The output is:

Code: Select all

ProgID    REG_SZ    Word.Document.12
A part of this output should go now into the property "myproperty":

Code: Select all

vboxcontrol guestproperty set /myproperties/myproperty <here comes the part, I want to have in the property myproperty>
When somehow in the code the string "Word" is, then ".Document.12" should go into myproperty.
When somehow in the code the string "Docume" is, then "nt.12" should go into myproperty.
When somehow in the code the sting "Wo" is, then "rd.Document.12 should go into myproperty.

(And all in one line.)

(I do not need the variables "Registry1" and "Registry1Ext", when they are not necessary. (At the beginning I thought, that I need them as a temporary storage.))

(I was never able to bring the whole output of ...

Code: Select all

C:\Users\D>reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v "ProgID"
... into the property myproperty. But I was able to bring a simple string like "abcdefghijk" into the property myproperty. So this is, why I want to bring only the part of ...

Code: Select all

ProgID    REG_SZ    Word.Document.12
... into the property myproperty, that is interesting)
Last edited by Furplado on 15 Feb 2021 07:43, edited 2 times in total.

Furplado
Posts: 12
Joined: 13 Feb 2021 10:18

Re: How to get all characters after a substring

#9 Post by Furplado » 14 Feb 2021 20:43

Eureka! wrote:
14 Feb 2021 14:15

Code: Select all

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call set YOURVAR=%BUFFER:*Word=%
(Untested)
Thank you.
Your code works in a way, that now I have in the variable YOURVAR what I need.

But:
I need the content of YOURVAR, at the end in my property "myproperty":

Code: Select all

vboxcontrol guestproperty set /myproperties/myproperty %YOURVAR%


So I have taken your code and have expanded it (scroll at the end):

Code: Select all

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call set YOURVAR=%BUFFER:*Word=%& call vboxcontrol guestproperty set /myproperties/myproperty %YOURVAR%
This expanded code seems to work. But only one time in the same cmd-window. When I change ...%BUFFER:*Word=%&... into ...%BUFFER:*Wor=%&... and start the modified code in the same cmd-window, then the property "myproperty" remains the same. Strange!



This is to demonstrait, what exactly happens, when I use the code two times in the same cmd-window, but modify it between the two times:
This is what I typed in my cmd-window:

Code: Select all

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

C:\Users\D>for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call set YOURVAR=%BUFFER:*Word=%& call vboxcontrol guestproperty set /myproperties/myproperty %YOURVAR%
This is the output an a test, what is in the property "myproperty" now:

Code: Select all

C:\Users\D>set BUFFER=Word.Document.12  & call set YOURVAR=%BUFFER:*Word=%  & call vboxcontrol guestproperty set /myproperties/myproperty %YOURVAR%Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.


C:\Users\D>vboxcontrol guestproperty get /myproperties/myproperty
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.

Value: .Document.12
-> It's ".Document.12" as it sould be.

Now I modify the code as mentioned (I change ...%BUFFER:*Word=%&... into ...%BUFFER:*Wor=%&...).
This is what I typed in the same cmd-window below the output from above:

Code: Select all

C:\Users\D>for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call set YOURVAR=%BUFFER:*Wor=%& call vboxcontrol guestproperty set /myproperties/myproperty %YOURVAR%
This is the output an a test, what is in the property "myproperty" now:

Code: Select all

C:\Users\D>set BUFFER=Word.Document.12  & call set YOURVAR=d.Document.12  & call
 vboxcontrol guestproperty set /myproperties/myproperty .Document.12
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.


C:\Users\D>vboxcontrol guestproperty get /myproperties/myproperty
Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 6
.1.2
(C) 2008-2020 Oracle Corporation
All rights reserved.

Value: .Document.12
-> As you can see it's again ".Document.12" . But it should be now "d.Document.12", after the modification.

(But it's not serious, because I guess, whenever I start the code again, then anyway a new cmd-window will start.
But it's strange behaviour.)

T3RRY
Posts: 132
Joined: 06 May 2020 10:14

Re: How to get all characters after a substring

#10 Post by T3RRY » 14 Feb 2021 23:10

Using The operator '&' to concatenate multiple commands in the same line results in a code block, the same as if you were to use parentheses to spread your for loops do statements onto their own lines.

Code: Select all

Set example=0
For /L %%a in (1 1 3)Do (
 Set example=%%a
 Echo(output:%example% actual:%%a
)
During code blocks, variables have the value (If any) they had prior to the execution of the code block. To allow the current value to be expanded, delayed expansion can be enabled prior to the loop or call can be used to reparse the command and achieve expansion.

Code: Select all

Set example=0
For /L %%a in (1 1 3)Do (
 Set example=%%a
 Call Echo(output:%%example%%
)

Eureka!
Posts: 123
Joined: 25 Jul 2019 18:25

Re: How to get all characters after a substring

#11 Post by Eureka! » 15 Feb 2021 02:57

You can skip the extra call-statement, which complicates things, by replacing

Code: Select all

set BUFFER=%x& call set YOURVAR=%BUFFER:*Word=%& call vboxcontrol guestproperty set /myproperties/myproperty %YOURVAR%
with:

Code: Select all

set BUFFER=%x& call vboxcontrol guestproperty set /myproperties/myproperty %BUFFER:*Word=%


What happens if you run these two commands on the CMD prompt?:

Code: Select all

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call vboxcontrol guestproperty set /myproperties/myproperty %BUFFER:*Word=%

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call vboxcontrol guestproperty set /myproperties/myproperty %BUFFER:*Wor=%

(BTW: Thank you for the new "layout". Now it's possible to follow what is going on and what you actually want to accomplish :))

Furplado
Posts: 12
Joined: 13 Feb 2021 10:18

Re: How to get all characters after a substring

#12 Post by Furplado » 15 Feb 2021 08:25

Eureka! wrote:
15 Feb 2021 02:57
What happens if you run these two commands on the CMD prompt?:

Code: Select all

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call vboxcontrol guestproperty set /myproperties/myproperty %BUFFER:*Word=%

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call vboxcontrol guestproperty set /myproperties/myproperty %BUFFER:*Wor=%
-> Works as expected:

The value of myproperty in the first command becomes ".Document.12" .
The value of myproperty in the second command becomes "d.Document.12"


Eureka! wrote:
15 Feb 2021 02:57
You can skip the extra call-statement, which complicates things, by replacing

Code: Select all

set BUFFER=%x& call set YOURVAR=%BUFFER:*Word=%& call vboxcontrol guestproperty set /myproperties/myproperty %YOURVAR%
with:

Code: Select all

set BUFFER=%x& call vboxcontrol guestproperty set /myproperties/myproperty %BUFFER:*Word=%
Thank you. The code with this replacement works now also in the same cmd-window. So I can now in this new code chanage <%BUFFER:*Word=> into <%BUFFER:*Wo=> and it works also in the same cmd-window.



Here is the new code in full length, gotten by replacing (see above):

Code: Select all

for /f "usebackq skip=1 tokens=3 delims= " %x in (`reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.docx\UserChoice" /v progid`) do set BUFFER=%x& call vboxcontrol guestproperty set /myproperties/myproperty %BUFFER:*Word=%


I think we have reached our goal. Thank you all for your kind help. :D

Post Reply