i have an array and a variable
SET users=nick_derus peter_parker john_simpsons cool_guy
set mid=freak
i need to create files named like the following:
"derus freak nick"
"parker freak peter"
"simpsons freak john"
"freak guy cool"
and i'm failing over and over again. any help on how to do it?
As they are unlikely file names, you'll have to determine the command you want to run yourself and change line five accordingly:
#Echo Off
Set users=nick_derus peter_parker john_simpsons cool_guy
Set mid=freak
For %%a In (%users%) Do For /F "Tokens=1* Delims=_" %%b In ("%%a") Do (
Echo createfile "%%c %mid% %%b")
pause
This ignores the fact your last example name doesn't follow the format of the others.
Related
I have a small problem with a .bat file that I have to build to manipulate a specific .csv.
I want the .bat to read the line of the file, and then check for the first three letters of that line. At the end there should be n-files where file xxx.csv contains the lines of the input.csv with xxx as the first three letters of line.
First things first, I don't even know if it is possible to do it this job in a batch-file, because the file has >85000 lines and may even get much bigger. So if it is impossible you can directly tell me that.
for /f "delims=" %%a in (input.CSV) DO (
echo %%~a:~0,3
pause
)
I want to "output" the first three letters of %%a.
It would be great if you could help me.
Phil
Substring substitution only works with environment variables (%var%), but not with metavariables (%%a) (as Mofi already commented). And because you are setting and using a variable within the same command block, you need delayed expansion:
setlocal enabledelayedexpansion
for /f "delims=" %%a in (input.CSV) DO (
set "var=%%~a"
echo !var:~0,3!
pause
)
(there are methods without delayed expansion, but they make use of call, which slows things down)
i have a problem, i need a code as in title. purpose of the script: i need to copy the file with a different language code, f.e. XXX_x_xYYY_EN_xx to XXX_x_xYYY_ES_xx and XXX_x_xYYY_DE_xx. So far i have this, but it does not work:
setlocal enableDelayedExpansion
for /l %%H in (1,1,2) do (
set endf[%%H]=!fName[%%H]:*_EN_=!
set trim[%%H]=_EN_!endf[%%H]!
set beginf[%%H]=!fName[%%H]:%trim[%%H]%=!
)
fName is set elswere, its something like this
fName[1]=XXX_x_xYYY_EN_xx
fName[2]=XXXXX_x_xYYYY_EN_x
Everything works except the set beginf(it spits out "beginf[1]=fName[1]:="), i've tryed myriads of % nad ! combos. Fun fuct it works in this case (other script, same puprose but work for only one file in directory, i'd like to make it more versatile):
set beginf=!NAME:%langcode%=!
help :) thanks!
So you have two diferent conversions for two array elements, isn't it? So you just need to match each filename with its corresponding conversion, right?
Something like this, perhaps?
set "conv[1]=ES"
set "conv[2]=DE"
for /l %%H in (1,1,2) do (
for %%c in (!conv[%%H]!) do set "newName[%%H]=!fName[%%H]:_EN_=_%%c_!"
)
I suggest you to read this answer.
EDIT: New method added
This code do exactly the same than the one in your posted answer:
#echo off
setlocal EnableDelayedExpansion
for %%a in (*.xml) do (
set "fName=%%a"
for %%c in (ES DE PL) do (
copy "%%a" "!fName:_EN_=_%%c_!"
)
)
A comparison of your code vs. this one:
You really not need an array of file names. If you create the array just to process its elements once with no further processing, then you are wasting the space occupied by the array. You may do the same thing using an individual file name variable.
Also, you not need an array of conversions. If you just want to repeat a command with several conversions, then it is much simpler to use a list of conversions instead.
It is a bad idea to use special characters as FOR replaceable parameters (where the documentation specifies a letter). Batch files are intrinsically cryptic, so there is no need to include additional complexities...
If you just want to process all files (no rename they) then it is simpler to use a plain for command instead of a for /F one on a 'dir /B' command. The second form requires to execute an additional copy of cmd.exe program and to create a temporary disk file...
If the newfName (array) variable is used just to execute the copy command in the next line, then such a variable is (again) a waste of space. You may create the new name in the copy command itself.
I found the solution :)
Full script with file counting below:
#echo off
setlocal enableDelayedExpansion
set /a count=0
for /f %%# in ('dir *.xml /b') do (
set /a count+=1
set fName[!count!]=%%~xn#
)
set "conv[1]=ES"
set "conv[2]=DE"
set "conv[3]=PL"
for /l %%H in (1,1,!count!) do (
for /l %%G in (1,1,3) do (
for %%c in (!conv[%%G]!) do (
set "newfName[%%G]=!fName[%%H]:_EN_=_%%c_!"
copy !fName[%%H]! !newfName[%%G]!
)
)
)
loops clarification:
for /l %%H - loops through the fName array
for /l %%G - loops through the lang table (conv) array
for %%c - combine above loops and copy files with changed names
thanks #Aacini for your input, it put me on the right tracks :)
I am trying to create a batch file that can look through a text file.
In the text file, there are rows of texts. I need to go through each row and if it contains the characters \\, then I want to echo that whole row.
I currently have the following, but it does not work. What happens is all the rows end up being echoed, instead of those that have \\.
for /f "delims=*" %%A in (list.txt) do (
if NOT "%%A"=="%%A:\\=%" (
echo %%A
)
)
Anyone able to advise what happens?
MC ND's suggestion of using find is for sure the easiest solution for your task. Anyway, I want to focus on your approach.
You cannot use sub-string replacement with for variable references. You need to store %%A in a normal environment variable and apply sub-string replacement there. However, since you are within a block of code (for loop), you must use delayed expansion. This is how it works:
setlocal EnableDelayedExpansion
for /F "delims=*" %%A in (list.txt) do (
set "TEST=%%A"
if NOT "!TEST!"=="!TEST:\\=!" (
echo/!TEST!
)
)
endlocal
I have a file C:\parameters.txt that contains different parameters, for example:
env_user=username123
env_pw=password123
env_url=example.com
Now I created a .cmd file that needs to get these values and put them in a variable, for example:
SET var_user=<Here I need 'username123'>
SET var_pw=<Here I need 'password123'>
SET var_url=<Here I need 'example.com'>
How do I write this in my cmd script to get the correct values for my variables?
You need to set a delimiter for = character so that words before/after = will be separated. Besides that, you need an array to set each of the parameters. You can do it like this:
#echo off
setlocal enabledelayedexpansion
set increment=0
for /f "tokens=1* delims==" %%a in (C:\parameters.txt) do (
set parameters_array[!increment!]=%%b
set /a increment+=1
)
echo %parameters_array[0]%
echo %parameters_array[1]%
echo %parameters_array[2]%
pause >nul
Keep in mind, array always starts from 0. You could change to set increment=1 if you prefer the array starts from 1.
Just a slight alternative to dark fang's solution, since your parameters.txt file's contents are already in the format of variable=value, you could
#echo off
setlocal
for /f "usebackq delims=" %%I in ("c:\parameters.txt") do set "%%I"
rem // display env_* variables
set env_
pause
The usebackq option allows you to quote the file name, which might be needed if you ever move c:\parameters.txt to a location containing spaces, ampersands, or other tricksy characters. It's a good habit to follow when reading the contents of text files with for /f.
Also, it's better not to use delayed expansion if you don't need it, as delayed expansion can sometimes corrupt values containing exclamation marks -- a situation that is reasonably possible when dealing with passwords.
I've found the solution thanks to different inputs.
#echo off
For /F "tokens=1* delims==" %%A IN (C:\parameters.txt) DO (
IF "%%A"=="env_user" set var_user=%%B
IF "%%A"=="env_pw" set var_pw=%%B
IF "%%A"=="env_url" set var_url=%%B
)
This will set the correct variables (not local) once the specific code name (before the = in parameters.txt) has been found.
I have got a system that generates CSV files containing time based data.
Some files have data from two different dates. I want to break up these files into two files, one containing the data from the first day, the other containing the data from the next day. The original file looks like this:
09.01.2015 00:00:00,0385 - Veerhaven,VP01 in bedrijf hoog toerental,K,Process message.
09.01.2015 00:00:00,0385 - Veerhaven,VP01 in bedrijf laag toerental,G,Process message.
08.01.2015 23:59:55,1475 - Schaatsbaan,PO01 in bedrijf,G,Process message.
08.01.2015 23:59:52,0311 - Abraham van Stolkweg,PO01 in bedrijf,G,Process message.
The first 10 Characters are the date of the event. I want to break up the file in two output files seperating the data from the two days. I have to do this using batch processing because it has to be done every day over a lot of files.
I hope someone can help me on my way. Thanks in advance.
#echo off
setlocal enableextensions disabledelayedexpansion
set "file=c:\somewhere\data.txt"
for %%f in ("%file%") do for /f "usebackq" %%a in ("%%~ff") do (
if not defined %%a (
findstr /b /c:"%%a" "%%~ff" > "%%~dpnf.%%a%%~xf"
set "%%a=1"
)
)
The first for command is used only to retrieve a reference to the file and being able to separate path, filename and extension (that will be used later to generate the output files).
Second for loop reads the input file and for each line retrieves the first token/field in the line using spaces as delimiters (the default behaviour in for /f command). This value is used to filter the input file and declare environment variables:
If the variable is not defined, it is the first time the value is seen, matching records are extracted from the input file to a new output file and the variable is defined.
If the variable is defined, this value has been seen and the corresponding output file generated, the extraction is skipped and the process continues reading the next line.
edited to adapt to comments
#echo off
setlocal enableextensions disabledelayedexpansion
set "files=c:\somewhere\*.txt"
set "outputFolder=c:\where\to\put\files"
for %%f in ("%files%") do (
setlocal
for /f "usebackq" %%a in ("%%~ff") do if not defined %%a (
findstr /b /c:"%%a" "%%~ff" > "%outputFolder%\%%~nf.%%a%%~xf"
set "%%a=1"
)
endlocal
)
The wildcard management in the input needs no changes: for %%f iterates over the indicated set, being it only a file or a set of files.
The output folder is stored in a environment variable. The redirection is changed to use the variable insted of the path of the input file.
As the variables used to determine if the indicated token has been processed needs to be deleted for each file processed, the loop that processes the file contents is wrapped in a pair of setlocal/endlocal that cleans the flag variables after each file has been processed
read HELP FOR to learn how to use the FOR command to loop over the lines of a file and parse its contents. Then, try
for /f "tokens=1,*" %%a in (timedata.txt) do (
echo %%a ... %%b
)
you see that you may use %%a to split the files by date, so you could figure out something like
for /f "tokens=1,*" %%a in (timedata.txt) do (
echo %%b >>timedata.%%a.txt
)
or more generically
set fn=%~dpn1
set fx=%~x1
for /f "tokens=1,*" %%a in (%~1) do (
echo %%b >>%fn%.%%a%fx%
)