batch file passing variable to a text file - variables

ECHO off
FOR /r %%a IN (*) DO (
IF NOT "%pth%"==%%~da%%~pa (
ECHO "%pth%">>Liste.txt
)
SET pth=%%~da%%~pa
)
I want to pass a path just one time; not for every file subdirectories includes. How %pth% string variable can be passed to a text file? Why does this code not work?
Is this code wrong?
FOR /r %%a IN (*) DO (
SET pth=%%~da%%~pa
ECHO %pth%>>Liste.txt
)
The code below works. It passes the paths for each file. If there is files more than one in a subdirectory it passes same path as many as the number o files. I don't want it. I want passing the same path once.
FOR /r %%a IN (*) DO ECHO %%~da%%~pa>>Liste.txt

You haven't told use very clearly (with an example) what you want to do.
Fundamentally, within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).
Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.
Two common ways to overcome this are 1) to use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var or 2) to call a subroutine to perform further processing using the changed values.
Hence
#ECHO off
setlocal enabledelayedexpansion
FOR /r %%a IN (*) DO (
IF NOT "!pth!"=="%%~dpa" (
ECHO "!pth!">>Liste.txt
)
SET "pth=%%~dpa"
)
should work (I haven't tried it)
OR
for /r /d %%a in (*) do >>liste.txt echo %%a
which is probably easier (produce a listing of all subdirectories)
Note that %%~da%%~pa is equivalent to %%~dpa
Edited to include required "

#Magoo: Thanks. You show me the right.
The code below is which I want; but "if conditional" does not work: ("!pth!"==%%~dpa) check is always return FALSE I think.
#ECHO off
setlocal enabledelayedexpansion
FOR /r %%a IN (*) DO (
IF NOT "!pth!"==%%~dpa (
ECHO %%~dpa>>Liste.txt
)
SET "pth=%%~dpa"
)
#Magoo: The question is how the code above works like your one line code below:
for /r /d %%a in (*) do >>liste.txt echo %%a
or like written by #MC ND:
dir /ad /s /b >> liste.txt

At last this works. Thanks everyone.
code:
#ECHO off
setlocal enabledelayedexpansion
FOR /r %%a IN (*) DO (
IF NOT "!pth!"=="%%~dpa" (
ECHO %%~dpa>>Liste.txt
)
SET "pth=%%~dpa"
)

dir /ad /s /b >> liste.txt
This should do the same your code trying to do: append all the subfolders into the target file.
The problem with the original code is how the parser handles variables. In batch files, when a line or a block of lines is reached, the parser removes all variable reads, replacing them with its value before executing the code. So, if inside a line/block a variable is changed, this changed value can not be retrieved inside the same line/block as the read operation was removed. The usual way to handle it is to enable delayed expansion. This allows to change where needed variable read syntax from %var% into !var!, indicating to the parser that the read operation must be delayed until the code is executed.
So, in your case, filtering the path of the files
setlocal enabledelayedexpansion
set "pth="
FOR /r %%a IN (*) DO (
IF NOT "!pth!"=="%%~dpa" (
ECHO "%%~dpa">>Liste.txt
SET "pth=%%~dpa"
)
)

Put the IF %pth% condition outside the FOR and it should work.
What exactly do you want to do ? Perhaps theres a simpler way.

Related

Batch - move files into alphabetical forders including unicode or 'strange' characters

I have some files and I want to move them inside alphabetical folder NOT previously created. With batch I want generate folders. Theses files must be moved inside these folders following files's first letter
I have a multi language file list inside my directory like this:
中文
alfa
35h
Ĕuid
لعربية
សេវិនខ្មែរ
I try this command to move files into alphabetic folders using first folder letter for ordering
#echo off
setlocal enabledelayedexpansion
for /d %%i in (*) do (
set first=%%i
set first=!first:~0,1!
md !first! 2>nul
if not "!first!" == "%%i" move "%%i" "!first!\%%i"
)
Nothing happens.
This part
for /d %%i in (*) do (
create folders and move folders and not files but I want move files inside generated folders (I don't want create folders previously)
You're currently using for /d which works on directories, not files. Since you have files, you need your for loop to work on them. If you just remove the /d, it will do so. However, note that this means it will also move the batch file itself. If you don't want that, then you'll need to put in logic to exclude it. Something like this:
#echo off
setlocal enabledelayedexpansion
for %%i in (*) do (
set first=%%i
if not "!first!" == "%0" (
set first=!first:~0,1!
md !first! 2>nul
if not "!first!" == "%%i" move "%%i" "!first!\%%i"
)
)
EDIT FOR ! SUPPORT
If the filename contains an exclamation mark, it won't work, because when delayed expansion is enabled, it sees that as part of a variable delimiter. The way to get around it is to assign the filename to a variable before you enable delayed expansion:
#echo off
setlocal
for %%i in (*) do (
set name=%%i
setlocal enabledelayedexpansion
if not "!name!" == "%0" (
set first=!name:~0,1!
md !first! 2>nul
if not "!first!" == "!name!" move "!name!" "!first!\!name!"
)
)

Removing everything after specific character in batch

SETLOCAL ENABLEDELAYEDEXPANSION
set "s=DIR D:\MyFolder /S /Q ^|FIND /i "Owner" ^|findstr /m /i "\.mkv$""
for /f "Tokens=5,6*" %%a in ('%s%') do (
SET _endbit=%%aa:*STRING=%
CALL SET _result=%%aa:%_endbit%=%%
>>%tmp%\list.txt echo %_result% %%b %%c
)
wscript "C:\my.vbs"
I am listing my files that owned by Owner and has extension mkv from MyFolder. I want to remove everything after specific character/word. I wrote that code. But It seems to be not working.
First of all, is it possible to do that? If so what is wrong with my code?
You came up with the same solution I was going to post on your other question - but I think you're missing some things. The line ending STRING=% is missing another % at the end, and the line %%aa:%_endbit%=%%, I'm not sure it can work directly on the variable from the for loop, and you need to store it in another variable first, and you probably need some expansions using ! characters too.
Here's what I had that seems to work, just as a test in a folder with three files in it, removing the end of the filename using E0 as the cutoff string:
SETLOCAL ENABLEDELAYEDEXPANSION
#echo off
for %%f in (*.mkv) do (
set FULLNAME=%%f
set ENDTEXT=!FULLNAME:*E0=!
call set TRIMMEDNAME=%%FULLNAME:!ENDTEXT!=%%
echo !TRIMMEDNAME!
)

How can i remove the extension of a filename which is saved in a batch variable?

first my batch script snippet (not working):
set _WRx32=wrar420.exe
set _WRx64=winrar-x64-420.exe
set _WRLNG=rarlng.rar
FOR %%f IN (_WRLNG, _WRx64, _WRx32) do set "%%f"="%%~nf"
[ for every variable name (!) in the list remove the extension from the variable content (!)
and save back to the same variable ]
Question: How can i remove the extension of the filenames which are saved in the
variables _WRLNG, _WRx64, _WRx32 and save this filename (without extension)
back to the same variables ??
i need something like: set var=%var~n% but that doesn't work. And in a FOR loop i don't know
how to convert the name from the (...variable names ...) list to the corresponding variable
so i can apply a parameter extension like "~n", "~nf" etc. on it.
Can anyone help me ?
Thanks
#echo off
setlocal EnableDelayedExpansion
set _WRx32=wrar420.exe
set _WRx64=winrar-x64-420.exe
set _WRLNG=rarlng.rar
FOR %%f IN (_WRLNG, _WRx64, _WRx32) do (
FOR %%g in (!%%f!) do set "%%f=%%~ng"
)
Try this:
FOR /f "delims=." %%f IN ("%_WRx32%") do set "_WRx32=%%f"
FOR /f "delims=." %%f IN ("%_WRx64%") do set "_WRx64=%%f"
FOR /f "delims=." %%f IN ("%_WRLNG%") do set "_WRLNG=%%f"
I tried a similar version on the command line, and it appears you can't do multiple variable variables in a for loop (that I know of).
So, you have two options:
If you know that the variables will always have a 4 character extension (including the period), then you could use something like set _WRLNG=%_WRLNG:~0,-4%. This will take the last 4 characters from the variable.
You have to do one loop per variable, and you need to fix up the way you are doing them. The proper way would be for /f %%i in ("%_WRLNG%") do set _WRLNG=%~ni.
Or, look at Endoro's answer for a better for loop example.
EDIT: Thought of another way:
#echo off
for /f "delims=. tokens=1,2" %%i in ("%var%") do set var=%%i

DOS Batch file - Copy file based on filename elements

I need to sort alot of files based on their filename. I would like to use a batch file to do it. I do know what I want but I am not sure of the correct syntax.
Example of filenames I work with: (They are all in the same directory originally)
2012_W34_Sales_Store001.pdf
2012_W34_Sales_Store002.pdf
2012_W34_Sales_Store003.pdf
2012_November_Sales_Store001.pdf
2012_November_Sales_Store002.pdf
2012_November_Sales_Store003.pdf
I would like to extract the information that are located between the "_" signs and put them into a different variable each time. The lenght of the informations contained between the _ signs will be different everytime.
Example:
var1="2012"
var2="W34" (or November)
var3="Sales"
var4="001"
If I am able to do this, I could then copy the files to the appropriate directory using
move %var1%_%var2%_%var3%_%var4%.pdf z:\%var3%\%var4%\%var1%\%var2%
It would need to loop because I have Store001 to Store050.
Also, there are not only Sales report, many others are available.
I hope I am clear.
Please help me realize this batchfile!
This script will make sure that it only attempts to move files that meet the pattern part1_part2_part3_part4.pdf
#echo off
for /f "eol=_ delims=" %%F in (
'dir /b *^|findstr /ix "[^_]*_[^_]*_[^_]*_[^_]*[.]pdf'
) do for /f "eol=_ tokens=1-4 delims=_." %%A in ("%%F") do (
move "%%F" "z:\%%C\%%D\%%A\%%B"
)
If needed, you could add md "z:\%%C\%%D\%%A\%%B" 2>nul before the MOVE in case the folders might not exist yet.
This script will move your files based on the values between the underscore to a like wise constructed path.
for %%f in (*.pdf) do call :handlefile %%f
:handlefile
set pad=z:
for /f "delims= tokens=1,* " %%a in ("%1") do call :step %%a %%b
rem this MOVES the file, maybe use echo first for testing
move "%fn%" "%pad%"
exit /B
:step
if !%2!==!! EXIT /B
set pad=%pad%\%1
for /f "delims=_ tokens=1,* " %%a in ("%2") do call :step %%a %%b
EXIT /B

batch files, variable expansion and substrings in loops

I can't wrap my head around the variable substitution mechanism of DOS batch files, especially in for loops.
Simplified batch problem: imagine the following directory
01foo.txt
02foo.dir (this is a directory)
bar01 (this is a directory)
bar02 (this is a directory)
i want to move all files/directories in this directory that do NOT start with 'bar' to a subdirectory that is bar+_the_first_2_characters_of_the_filename_or_directory_name.
In this case, 01foo.txt would be moved into bar01 and 02foo.dir would be moved into bar02.
The following script is my first attempt:
setlocal EnableDelayedExpansion
for %%A in (*) do (
set _x=%%A
if (!_x:~0,2! NEQ "bar") move %%A bar!_x:~0,2!
)
endlocal
apart from the fact that this seems to loop only for files, it simply doesn't work at all :-).
I get an error in the if statement saying "3! was unexpected at this time"
Any idea on how to improve the situation/script?
Thanks
It's only a problem of the syntax...
The IF statement does not expect not accept surrounding brackets.
The the comma in !_x:~0,2! breaks the IF-statment, you could quote both parts or move it into an own set prefix=!_x:~0,2!" line.
If you quote "bar" you also need to quote "!prefix!".
That's all
setlocal EnableDelayedExpansion
for %%A in (*) do (
set "_x=%%A"
set "prefix=!_x:~0,2!"
if "!prefix!" NEQ "bar" move %%A bar!prefix!
)
endlocal