I have the following Problem:
I have 2 functions/labels called STARTERand Get_age. The Get_age function stores ages and names in some related variables and shall return the age of the person i passed to it (passed the name).
But the variable which shall store the return value -> means !arr[%%i].age!seems to be empty all the time. I think this is may of the (ENDLOCAL ...) block.
What confuses me too: if i only want to return the %%i inside the (ENDLOCAL ...) block it works fine, but when there are some !exclamation marks! the variable seems to get empty.
How can i now return the age easily without bloating the code? PS: This piece of code is only a small example to give a better view on it.
ThankĀ“s a lot
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
REM FUNCTION WHICH ASKS STORES A NAME AND ASKS FOR ITS AGE
:STARTER
setlocal
set "person=Niels"
call :Get_age "%person%" "readback"
echo %person% is -%readback%- years old.
pause
exit /b 0
REM FUNCTION WHICH RETURN THE AGE TO THE GIVEN NAME
:Get_age
setlocal
set "searchName=%~1"
set "retVal=%~2"
set "arr[0].name=Niels"
set "arr[0].age=5"
set "arr[1].name=Julia"
set "arr[1].age=2"
set "arr[2].name=Claus"
set "arr[2].age=9"
set "arr_size=2"
REM Go through the arr and return the age to the given name
for /l %%i in (0 1 %arr_size%) do (
if "!arr[%%i].name!" equ "%searchName%" (
(ENDLOCAL
set %retVal%=!arr[%%i].age!
)
)
)
exit /b 0
Perhaps this structure, which enables delayed expansion only when needed, and ends it again as soon as it has no further purpose, will work better for you:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Rem Stores a name, determines their age and returns it.
Set "person=Niels"
Call :Get_Age "%person%" "readback"
Echo %person% is -%readback%- years of age.
Pause
Exit /B 0
:Get_Age
Set "arr[0].name=Niels"
Set "arr[0].age=5"
Set "arr[1].name=Julia"
Set "arr[1].age=2"
Set "arr[2].name=Claus"
Set "arr[2].age=9"
Set "arr_size=2"
For /L %%G In (0,1,%arr_size%) Do (
SetLocal EnableDelayedExpansion
If /I "!arr[%%G].name!" == %1 (
For %%H In ("!arr[%%G].age!") Do (
EndLocal
Set "%~2=%%~H"
)
) Else EndLocal
)
GoTo :EOF
You could store the value and return it after the loop.
set "found="
for /l %%i in (0 1 %arr_size%) do (
if "!arr[%%i].name!" equ "%searchName%" (
set "found=!arr[%%i].age!"
)
)
(
ENDLOCAL
set "%retVal%=%found%"
)
goto :eof
I have a tab delimited txt file and I am trying to find the value 0 in the last column in every line then rename that value from 0 to K.This is the code I have come up with so far but I can't get the values to change. What am I doing wrong here?
ECHO ON
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=E:\psexport"
SET "destdir=E:\psexport"
SET "filename1=%sourcedir%\nk3.txt"
SET "outfile=%destdir%\nk4.txt"
(
FOR /f * IN ("%filename1%") DO (
SET "line=*"
SET "line=!line:0=K"
ECHO !line!
)
)>"%outfile%"
GOTO :EOF
`
You are using bang where I would expect to see percentage. Also, I'm not sure about that second set statement.
See my code example below. In the echo command I am calling line, with the variable substitution of replace 0 with K. It's wrapped in percentages because that whole expression is the variable we want to echo.
ECHO ON
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=E:\psexport"
SET "destdir=E:\psexport"
SET "filename1=%sourcedir%\nk3.txt"
SET "outfile=%destdir%\nk4.txt"
(
FOR /f * IN ("%filename1%") DO (
SET "line=*"
ECHO %line:0=K%
)
)>"%outfile%"
GOTO :EOF
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=E:\psexport"
SET "destdir=E:\psexport"
SET "filename1=%sourcedir%\nk3.txt"
SET "outfile=%destdir%\nk4.txt"
(
FOR /f "usebackq delims=" %%a IN ("%filename1%") DO (
SET "line=%%a"
IF "!line:~-2!"==" 0" (
ECHO !line:~0,-2! K
) ELSE (
ECHO %%a
)
)
)>"%outfile%"
GOTO :EOF
The for syntax requires a metavariable - I've used %%a - which is alphabetical and case-sensitive.
The modifier usebackq is used because the name of the file being read is quoted.
delims= means no delimiters, so the entire file line is delivered to %%a.
To use substringing, we need to transfer the value to a standard environment variable, then test that the last two characters of the line read are 0 so that 10 does not get modified. If the test is true, echo the line from the beginning (character 0) through to the end - 2 characters and append K, otherwise, regurgitate the original line.
The set syntax you were using replaces every 0 with K.
I am trying to write a batch file in windows which copies / appends a new column at the starting of CSV file . and then populates with values 0 and 1 alternately
For Example:
F1,F2,F3
1,2,3
1,2,3
2,3,4
3,4,5
Now I wish to add a new column at first and add values to them
ex
F0,F1,F2,F3
0,1,2,3
1,1,2,3
0,2,3,4
1,3,4,5
Just append 0 for all even row numbers and 1 for all odd rows
Below is the code that I have written, but that just adds 0 to all rows, but I want 0 and 1 alternately
#echo off > newfile.csv & setLocal enableDELAYedeXpansion
for /f "tokens=* delims= " %%a in (J_CAFE27032018_090325.csv) do (
>> newfile.csv echo a,%%a
)
A c equivalent would be having a for loop for all even and odd columns
for(i=0;i<n;i+2)
{
add 0
}
for(i=0;i<n;i++)
{
add 0
}
Would you please help me with the batch file equivalent to traverse each odd and even rows.
This method is the same as Aacini's however it prepends the header line with #,, (can be modified).
#Echo Off & SetLocal EnableDelayedExpansion
Set "i=" & (For /F "UseBackQ Delims=" %%A In ("J_CAFE27032018_090325.csv") Do (
If Defined i (Echo !i!,%%A) Else Set "i=1" & Echo #,%%A
Set /A "i=(i+1)%%2"))>newfile.csv & Exit /B
This is one of several ways to do it:
#echo off & setLocal enableDELAYedeXpansion
set "i=0"
(for /f "delims=" %%a in (J_CAFE27032018_090325.csv) do (
echo !i!,%%a
set /A "i=(i+1)%%2"
)) > newfile.csv
However your original logic dos not correctly process the header (first) line...
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q50041056.txt"
SET "outfile=%destdir%\outfile.txt"
SET "firstline=Y"
SET "zerostart=Y"
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
IF DEFINED firstline (
ECHO F0,%%a
SET "firstline="
) ELSE (
IF DEFINED zerostart (
ECHO 0,%%a
SET "zerostart="
) ELSE (
ECHO 1,%%a
SET "zerostart=Y"
)
)
)
)>"%outfile%"
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used a file named q50041056.txt containing your data for my testing.
Produces the file defined as %outfile%
The usebackq option is only required because I chose to add quotes around the source filename.
This solution uses the fact that if defined interprets the current status of the variablename, so the variable in question is simply toggled between a value and nothing.
I would do it the following way -- given that no line of the input CSV file (data.csv) exceeds an overall length of 1021 characters/bytes:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=%~1" & rem // (CSV file to process; use first argument)
set "_SEP=," & rem // (separator character)
set "_HEAD=F0" & rem // (header text for new column)
set /A "_MOD=2" & rem // (divisor for modulo operation)
set /A "_OFF=0" & rem // (offset for modulo operation)
setlocal EnableDelayedExpansion
rem // Determine number of lines contained in CSV file:
for /F %%C in ('^< "!_FILE!" find /C /V ""') do set /A "COUNT=%%C"
rem // Read from CSV file:
< "!_FILE!" (
rem // Check whether header text is defined:
if defined _HEAD (
rem // Header text defined, so read current header:
set "LINE=" & set /P LINE=""
rem // Prepend header text for new column to current line:
echo(!_HEAD!!_SEP!!LINE!
rem // Decrement number of lines:
set /A "COUNT-=1"
)
rem // Process remaining lines in a loop:
for /L %%I in (1,1,!COUNT!) do (
rem // Read current line:
set "LINE=" & set /P LINE=""
rem // Perform modulo operation:
set /A "NUM=(%%I+_OFF-1)%%!_MOD!"
rem // Prepend remainder of division to current line:
echo(!NUM!!_SEP!!LINE!
)
)
endlocal
endlocal
exit /B
This approach uses input redirection to read from the input CSV file.
To write the output to another CSV file, say data-mod.csv, rather than to the console, use the following command line, assuming the script is called prepend-modulo.bat and the input CSV file is named data.csv, and both reside in the current directory:
prepend-modulo.bat "data.csv" > "data_mod.csv"
I have written this batch code:
#echo on
set variable=z
set t=%time:~0,2%
IF %t% LSS 12 (
%z%=_1
) ELSE (
%z%=_2
)
And when run the batch file from command window, I get this error:
IF 14 LSS 12 (_1) ELSE (_2)
'_2' is not recognized as an internal or external command, operable program or batch file.
Where is the mistake in my code resulting in this error message?
I'm not sure what you want to achieve. I guess you want to check the condition %t%<12 and set your variable z to _1 if this is the case and to _2 otherwise.
Your error is that %z%=_1 is not a valide statement. To assign a value to a variable you always have to use SET:
SET z=_1 will result in %z% holding the value _1. So your code can be fixed like this:
#echo on
set variable=z
set t=%time:~0,2%
IF %t% LSS 12 (
SET z=_1
) ELSE (
SET z=_2
)
Based on the rest of your code you also might need to add the line SETLOCAL EnableDelayedExpansion at the beginning of your code and access your variable z as !z! instead of %z% below your IF-construct.
EDIT:
To fit your desctiprion from your comment you should do this:
#echo on
set t=%time:~0,2%
IF %t% LSS 12 (
SET z=_1
) ELSE (
SET z=_2
)
set folderName=%date%%z%
mkdir %folderName%
An easier way would be to set folderName inside the IF-counstruct:
#echo on
setlocal enabledelayedexpansion
set t=%time:~0,2%
IF %t% LSS 12 (
set folderName=%date%_1
) ELSE (
set folderName=%date%_2
)
mkdir !folderName!
Im trying to write batch file code to check whether given line is present in text file or not. If it is present I want to get specific line(depending on line number) after that line into variable..
Can anyone help me?
For example
I have text file as...
EX1
EX2
Ex3
EX4
Ex5
now I want to search weather Ex3 is present in batch file or not.
If it is present I want Ex5(2nd line after that) into variable.
Thanks in advance
This works on my box:
#echo off
SET searchterm=Ex3
SET /a lineafter=2
SET filename=lst.txt
:: --------------
SETLOCAL ENABLEDELAYEDEXPANSION
SET /a c=0
FOR /F "delims=" %%i IN (%filename%) DO (
if !c! GTR 0 (
IF %lineafter% EQU !c! (
SET result=%%i
GOTO :linefound
)
SET /a c=!c! + 1
) ELSE (
IF "%%i"=="%searchterm%" (
SET /a c=1
)
)
)
echo No result
GOTO :EOF
:linefound
echo Result: %result%
Just enter your values in the lines 2-4.