Batch script to read the last word of a sentence - windows

I want to get last word from a sentence or file path
I tried solutions from other articles and forums but can't seem to figure it out. here is what I have so far
#echo off
set a="C:\Some\Random\File\Path.txt"
echo %a%
set b=%a:\= %
echo %b%
for /f "tokens=*" %%a in (%b%) do #echo %%a %%b %%c
pause
All I need is the last word of what ever file path I put in %a%

Just to answer specifically on your question:
#echo off
set "a=C:\Some\Random\File\Path.txt"
for %%i in (%a%) do echo %%~nxi
pause
Also see how I used the double quotes on the setting of the variable, This allows us to get rid of any wanted whitespace after the value, and also if we add the quotes after the equal, they become part of the value, which is not what we really want.
To understand the variable references, for from cmdline for /? I suggest you also see set /?
Additionally, based on your comment, if you want to set it as a viarble, simply do it :)
#echo off
set "a=C:\Some\Random\File\Path.txt"
for %%i in (%a%) do set variablename=%%~nxi
echo %variablename%
pause

While Gerhards solution IS preferable (for path), your approach wasn't that bad.
You just have to use a simple for,
so it iterates over the space seperated elements which therefor have to be unquoted.
Repeatedly setting the same variable will have the last value/word persisting.
:: Q:\Test\2019\01\18\SO_54246604.cmd
#echo off
set "a=C:\Some\Random\File\Path.txt"
echo %a%
for %%a in (%a:\= %) do Set "b=%%a"
echo %b%
pause
> SO_54246604.cmd
C:\Some\Random\File\Path.txt
Path.txt

Related

Batch script does not echo contents of a variable and pause not working

I am working on a script which iterates over every file in a specific folder and reads some information from, and numbers each.
So I am running over the files with a for-loop and that is working correctly. Now I added a variable i which should increment on each iteration of the loop.
I used set /a i=0 and inside the for-loop set /a i+=1 and this Set command does print the number to console. My problem now is that the set command prints the number, but when I echo the number with echo %i% it will always print 0 and not the increasing value. I also tried echo !i! but that does not work at all. It just prints !i! in the console.
I also added a pause command to the end of the script, but that gets ignored entirely.
This is my batch script:
#echo off
setlocal EnableDelayedExpansion
set /a i=0
for /r %%n in (Links\*.lnk) do (
set /a i+=1
echo.
echo [Button!i!Back]
get.bat "%%n"
)
pause
This is an example of the output:
45
[Button!i!Back]
###HudIcons\VLC media player.ico
D:\Programme\VideoLAN\VLC\vlc.exe
I also just realized, that for the first time the loop runs, the !i! does work correctly and prints the number, but not afterwards.
I know that I should probably not be calling the other batch file like this, but that is temporary.
Any ideas why this is behaving so weird?
Perhaps it would be easier for you without the Set /A incrementing method, and therefore no need for delayed expansion. The alternative methodology could involve using findstr.exe to provide the counting:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /F "Tokens=1,* Delims=:" %%G In ('Dir /B /S /A:-D "Links\*.lnk" ^
2^> NUL ^| %SystemRoot%\System32\findstr.exe /EILN ".lnk"') Do (Echo=
Echo [Button%%GBack]
Call "get.bat" "%%H")
Pause
You use percentages symbol to call a variable %Variable%
and to echo it echo %variable%
to set one set variable=value Hope this helps you.

Get a part of the current path

I would like to get a part of the current directory where my batch script is from.
The location is something like this : Y:\abc\def\ghi\jkl\script.bat
I just want to keep what's after Y:\abc\def\  (that is \ghi\jkl)
How to do this ?
I'm using the code below for getting the full path but how to make a delimitation ?
for /f %%a in ("%CD%") do set CURR=%%a
echo %CURR%
Thank you for your precious help.
Based upon your stated "directory where my batch script is from", the following should suffice, (the last line is added for demonstration purposes, please change it as necessary):
#Set "x=%~dp0"&SetLocal EnableDelayedExpansion
#Set "i=0"&Set "x!i!=%x:\="&Set /A i+=1&Set "x!i!=%"
#Set /A i-=1,y=i-1
#If %i% Lss 1 (Set "z=%x0%\")Else (If %i% Equ 1 (Set "z=%x0%\%x1%"
)Else Set "z=!x%y%!\!x%i%!")
#EndLocal&Set "y=%z%"
#Echo %x% becomes %y%&Pause
I have made it so that if the scripts directory isn't deep enough, the full path will still be output.
If you want to use the current directory instead of the scripts location, change %~dp0 on line 1 to %__CD__% or %CD%\ as needed.
I believe that maybe you could put the section to be cut inside a txt file and then manipulate the string from the loop in the file, like this:
echo %cd% > path.txt
for /f "tokens=3,* delims=\" %%a in (path.txt) do echo %%b
Determining the depth with the argument tokens=3 with the delimiter character being "\".
#echo off
setlocal
set "reversed="
set "fromdir=%~dp0"
for %%A in ("%fromdir:\=" "%") do call set "reversed=%%~A\%%reversed%%"
for /f "tokens=1-2 delims=\" %%A in ("%reversed%") do set "result=\%%B\%%A"
echo %result%
pause
If the path segments can be reversed, then getting the last 2 segments is a known number for setting the tokens option of 1-2 as they would become the 1st 2 segments. The 1st for loop does the reversing. The 2nd for loop gets the 1st 2 tokens and is set to result in reverse order, which is the original order.
The fromdir is set for the script directory %~dp0, though it can be set with %cd% if is wanted.
View set /? for how "%fromdir:\=" "%" does replacement of \ with " " so that the path segments become individual arguments i.e. "C:\dir1\dir2\dir3" becomes "C:" "dir1" "dir2" "dir3".

Double quotes in delims=?

I'm very new to batch scripting, but in my last question I was trying to extract a link from a line of text, specifically:
83: href="https://beepbeep.maxresdefault.rar"><img
What I want out of it is this:
https://beepbeep.maxresdefault.rar
Someone suggested using for /f to separate the string, and I'd like to separate it every " mark, taking only the second token, as what I want is trapped between the two "".
Here is what I've got:
for /f "delims=^" tokens=^2" %%G in (output2.txt) do #echo %%G %%H >> output3.txt
The batch crashes at this point, I'm guessing it's the wrong syntax, but I'm not sure where the issue is, maybe in the " part?
See how we delimit on double quotes, without surrounding quotes. We have already assigned the variable between the quotes to %%a but if we did not, then to remove the double quotes from the string we expand the variable %%a to %%~a (see for /? on variable expansion):
#for /f delims^=^"^ tokens^=2 %%a in (output2.txt) do #echo %%~a
Neat problem.
I'd do it this way:
SETLOCAL ENABLEDELAYEDEXPANSION
for /F "tokens=2 delims=^>=" %%i in (output2.txt) do (
set x=%%i
set x=!x:"=!
echo !x! >> output3.txt
)
Notes:
Instead of tokenising on the quote, I've tokenised on = (before) and > (after). Because, as you already know, quotes are hard
I always do the delims last. Otherwise it might think the space between delims and tokens is a delimeter.
Then it uses the SET syntax that allows you to substitute one character for another to replace all occurances of the double quote with nothing.
The SETLOCAL ENABLEDELAYEDEXPANSION is necessary because otherwise, each evaluation of the %x% in the loop uses the original value of %x% which is probably wrong. I always have this as the second line in my batch file.
Judging by how much you've already got, I'm guessing you've seen it, but if you haven't, I've found ss64.com to be the best resource.
https://ss64.com/nt/syntax-dequote.html

Why does my for-loop not increase my variable?

I program a batch file, but I'm new to for-loops which I need.
I now know how the syntax works, but I cannot figure out why my loop does not do what it should.
This code is an extract from my file:
#echo off & setlocal enabledelayedexpansion
set /p file=:
set /a numberofgoals=0
for /f "delims=" %%a in ("%file%.txt") do set /a "numberofgoals+=1"
echo %numberofgoals%
pause > nul
If I did everything right my output should be the length of the specified textfile and it worked for me before, but apperently I changed something in the code that I'm not sure about and the output of %numberofgoals% is everytime exactly 1 now, regardless of how long my text file is.
My question is: What have I done wrong and why is the output 1 now? I cannot even remember having changed something there...
EDIT: I changed "delims=" into "usebackq delims=" as suggested and it works now, thank you.
The quotes in the for loop's parentheses mean "process this string" rather than "read this file". Use the usebackq option to indicate that the quotes are providing a filename:
for /f "usebackq delims=" %%a in ("%file%.txt") do set /a "numberofgoals+=1"
and you should be golden.
Type help for in your cmd window for the gory details.

Batch For Loop Escape Asterisk

I am attempting to create a batch for loop (Windows XP and newer command prompts) that iterates through a string containing one or more asterisks. How can I do this? Here is an example:
#FOR %%A IN (A* B) DO #ECHO %%A
The expected output (what I am trying to get) is the following:
A*
B
However, what I am actually getting with the command above is B and only B. For some reason, everything with an asterisk is being ignored by the loop. I have attempted escaping the asterisk with 1-4 carets (^), backslashes (\), percent signs (%), and other asterisks (*), all to no avail. Thanks in advance for illuminating me.
IN CASE YOU WANT MORE INFORMATION:
The purpose of this is to parse a path out of a list of space-separated partial paths. For example, I want to copy C:\Bar\A.txt, C:\Bar\B.txt, and C:\Bar\C*.txt to C:\Foo\ using the following approach:
#SET FILE_LIST=A B C*
#FOR %%A IN (%FILE_LIST%) DO #COPY C:\Bar\%%A.txt C:\Foo\
If there is another alternative way to do this (preferably without typing each and every copy command since there are ~200 files, which is the same reason I don't want to store the full path for every file), I would appreciate the help. Thanks again,
-Jeff
the asterisks works the way its intended, in your case,
#FOR %%A IN (A* B) DO #ECHO %%A
expands A* to all the files that begin with A.
A possible way to do what you want, is just to use this expansion
#ECHO off
PUSHD C:\bar
SET FILE_LIST=A.txt B.txt C*.txt
FOR %%A IN (%FILE_LIST%) DO (
IF EXIST %%A COPY %%A C:\Foo\
)
POPD
This may help:
#echo off
set "it=a*b .txt-b*.txt-c*.txt-d.txt"
set /a i=0,fn=3
:startLoop
set /a i=i+1
for /f "tokens=%i%delims=-" %%m in ("%it%") do echo %%m
if %i% lss %fn% goto:startLoop

Resources