Using Variable as Substring Parameter in Batch - windows

I'm trying to extract the string before the last slash that I retrieve from my function; :FIND_SLASH. But when I echoed the result, it is displaying the variable name ndxOfSlash, instead of the extracted string.
The list.txt contains the sample input below.
Sample Input:
AAA/BBBB/CCC/test.txt
Expected output:
AAA/BBBB/CCC/
Actual output:
ndxOfSlash
Code Snippet
#echo off
setlocal EnableDelayedExpansion
FOR /F "tokens=*" %%x in (list.txt) DO (
set tempname=%%x
call :FIND_SLASH indexSlash
set ndxOfSlash=!indexSlash!
call set fileDir=!!tempname:~0,!ndxOfSlash!!!
echo !fileDir!
)
I also tried replacing the variable parameter; ndxOfSlash, with an actual number, and it was able to display the expected output.
I referred to this site when doing the substring.

call set fileDir=%%tempname:~0,!ndxOfSlash!%%
should fix the problem.

Related

Why is my variable not passing all the data to a text file in my batch script?

I'm trying to parse a file that contains data, it has some numbers which I want to parse, store and use them as variables in the future. The problem is, these numbers are updated often so that's why I'm parsing them whenever I run my script.
The problem, is that when I collect the data as a variable in a for loop, it's not getting passed to my text file properly.
#echo off
setlocal EnableDelayedExpansion
for /f "skip=104 eol=/ tokens=4 delims=," %%A in (file location) do (
echo %%A
echo %%A > UICNumbers.txt
)
This is the output of the echo %%A command:
UIC00000701991
UIC00000710996
UIC00001701890
UIC00002701890
UIC00001701898
UIC00002701898
When I open the UICNumbers.txt file all I see listed is:
UIC00002701898
which is the last entry in the for loop variable. I tried changing the output to >> but this means every time I run the command it repeats every entry.

Windows Batch file - strip leading characters

I have a batch file which copies some local files up to a google storage area using the gsutil tool. The gsutil tool produces a nice log file showing the details of the files that were uploaded and if it was OK or not.
Source,Destination,Start,End,Md5,UploadId,Source Size,Bytes Transferred,Result,Description
file://C:\TEMP\file_1.xlsx,gs://app1/backups/file_1.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.804000Z,CPHHZfdlt6AePAPz6JO2KQ==,,18753,18753,OK,
file://C:\TEMP\file_2.xlsx,gs://app1/backups/file_2.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.813000Z,aTKCOQSPVwDycM9+NGO28Q==,,18753,18753,OK,
What I would like to do is to
check the status result in column 8 (OK or FAIL)
If the status is OK then move the source file to another folder (so that it is not uploaded again).
The problem is that the source filename is appended with "file://" which I can't seem to remove, example
file://C:\TEMP\file_1.xlsx
needs to be changed into this
C:\TEMP\file_1.xlsx
I am using a for /f loop and I am not sure if the manipulation of the variables %%A is different within a for /f loop.
#echo off
rem copy the gsutil log file into a temp file and remove the header row using the 'more' command.
more +1 raw_results.log > .\upload_results.log
rem get the source file name (column 1) and the upload result (OK) from column 8
for /f "tokens=1,8 delims=," %%A in (.\upload_results.log) do (
echo The source file is %%A , the upload status was %%B
set line=%%A
set line=!line:file://:=! >> output2.txt echo !line!
echo !line!
)
The output is like this.
The source file is file://C:\TEMP\file_1.xlsx , the upload status was OK
The source file is file://C:\TEMP\file_2.xlsx , the upload status was OK
I'm expecting it to dump the altered values out into a new file but it is not producing anything at the moment.
Normally I would extract from a specific character to the end of the string with something like this but it doesn't work with my For/f loop.
%var:~7%
Any pointers or a different way of doing it greatly appreciated.
Since the part to remove seems fixed it is easier to use substrings.
Also using for /f "skip=1" evades he neccessity of the external command more +1 and another intermediate file.
#echo off & setlocal EnableDelayedExpansion
type NUL>output2.txt
for /f "skip=1 eol=| tokens=1,8 delims=," %%A in (.\upload_results.log) do (
echo The source file is %%A , the upload status was %%B
set "line=%%A"
set "line=!line:~7!"
echo(!line!>>output2.txt
echo(!line!
)
File names and paths can contain also one or more exclamation marks. The line set line=%%A is parsed by Windows command processor a second time before execution with enabled delayed expansion. See How does the Windows Command Interpreter (CMD.EXE) parse scripts? Every ! inside the string assigned to loop variable A is on this line interpreted as begin or end of a delayed expanded environment variable reference. So the string of loop variable A is assigned to environment variable line with an unwanted modification if file path/name contains one or more exclamation marks.
For that reason it is best to avoid usage of delayed expansion. The fastest solution is for this task using a second FOR to get file:// removed from string assigned to loop variable A.
#echo off
del output2.txt 2>nul
for /F "skip=1 tokens=1,8 delims=," %%A in (upload_results.log) do (
echo The source file is %%A , the upload status was %%B.
for /F "tokens=1* delims=/" %%C in ("%%~A") do echo %%D>>output2.txt
)
Even faster would be without the first echo command line inside the loop:
#echo off
(for /F "skip=1 delims=," %%A in (upload_results.log) do (
for /F "tokens=1* delims=/" %%B in ("%%~A") do echo %%C
))>output2.txt
The second solution can be written also as single command line:
#(for /F "skip=1 delims=," %%A in (upload_results.log) do #for /F "tokens=1* delims=/" %%B in ("%%~A") do #echo %%C)>output2.txt
All solutions do following:
The outer FOR processes ANSI (fixed one byte per character) or UTF-8 (one to four bytes per character) encoded text file upload_results.log line by line with skipping the first line and ignoring always empty lines and lines starting with a semicolon which do not occur here.
The line is split up on every occurrence of one or more commas into substrings (tokens) with assigning first comma delimited string to specified loop variable A. The first solution additionally assigns eighth comma delimited string to next loop variable B according to ASCII table.
The inner FOR processes the string assigned to loop variable A with using / as string delimiter to get assigned to specified loop variable file: and to next loop variable according to ASCII table the rest of the string after first sequence of forward slashes which is the full qualified file name.
The full qualified file name is output with command echo and appended either directly to file output2.txt (first solution) or first to a memory buffer which is finally at once written into file output2.txt overwriting a perhaps already existing file with that file name in current directory.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
for /?
See also the Microsoft article about Using command redirection operators for an explanation of the redirections >, >> and 2>nul

Extract numeric part from a string using batch scripting

I have a file name abcd_1234.java. How can i able to extract only the number and store into a variable using batch scripting. The output should come as 1234.
There is no fixed length of the string, if the string is testfile_345.java the output should be 345.
In Unix i find it easy, but in batch scritping i am not getting the proper commands.
Please help.
Thanks.
To get the Last underscore delimited section of a file name,
use string substitution to replace the underscores with a space and iterate with a simple for.
#Echo off & setlocal EnableDelayedExpansion
for %%A in (*_*.java) do (
set "fname=%%~nA"
set "fname=!Fname:_= !"
for %%B in (!fname!) Do set Number=%%B
Echo number from %%A is !Number!
)
Sample output:
number from abc__def_123.java is 123
number from abc_123.java is 123

Windows Batch - Findstr and assign to a variable

I am trying to find a string in a file and assign the results to a variable for further processing. But for some reasons the code below doesn't work.
My string is always available on the 2nd line so I tried the code below, from which I can print the correct string on the console, but cannot assign it to a variable:
for /f "tokens=1*delims=:" %%G in ('findstr /n "^" C:\myfolder\payload.xml') do if %%G equ 2 echo %%H
Problem: Using the above method I'm unable to store the result in a variable
I have tried another method as well:
findstr /g "FilePath" C:\myfolder\payload.xml>>D:\Data\tmp.txt
set /p "Prev_FileName="<D:\Data\tmp.txt
echo %Prev_FileName%
Problem: with this method getting the output in the file tmp.txt but not in the variable.
In both contexts used SETLOCAL EnableDelayedExpansion
Could you please help as I am a beginner?
There are no unusual steps that need to be taken to set a variable in either context. How do you know the variable has not been set?
The first code you posted does not attempt to set anything, though if you changed the echo %%H into set "Prev_FileName=%%H", then it should work just find.
The second code should be setting the variable.
Why do you think your variable is not being set? I suspect you are doing something like echo %Prev_FileName%, and not seeing your expected result. That could happen if you are within a parenthesized block of commands, since they are all parsed at once, and %Prev_FileName% is expanded at parse time. You say you setlocal enableDelayedExpansion, but that does nothing unless you you also change the syntax for variable expansion. You should use echo !Prev_FileName! instead.

Batch script: IF compaison is not working as expected

FOR /F "tokens=*" %%A IN ('gpresult /r ^| FIND "string"') DO SET Result=%%A
if '%Result%'=='this is where the word string shows up'
echo Success > %homepath%\Desktop\Success.txt
Does not actually write the file to the desktop even though the strings match.
You need
setlocal enabledelayedexpansion
at the top of your batch file, and then instead of
'%Result%'=='this is where the word string shows up'
you need
'!Result!'=='this is where the word string shows up'
- notice the ! instead of %. Otherwise, %Result% is expanded when the batch file is first parsed, at which point the Result variable does not contain anything. These changes mean that it delays parsing it until its within the for loop, by which point it will have been populated appropriately.
Try using setlocal enabledelayedexpansion in your code. Then access your variables using "!variable!" instead of "%variable%".
Also make sure if %%A is fetching the required token or not.
The echo should be on the same line as the if:
if '%Result%'=='this is where the word string shows up' echo Success > %homepath%\Desktop\Success.txt
or put parentheses around it:
if '%Result%'=='this is where the word string shows up' (
echo Success > %homepath%\Desktop\Success.txt
)

Resources