Batch: Save directory listing into list-variable - windows

I want to take a file from a source directory (C:\Users\Desktop\Source\Test.xlsx) and want to replicate it to several folders, all having the same structure. So I have to change just one folder name. All done via one batch file and just one log-file which is created afterwards.
To have dynamically expansion of my batch-procedure here, I want to do a filtering of the elements of the root folder (C:\Users\Desktop\Replica\), which shows me the childs (one two three four five) where the file needs to be copied at inside a testfolder. There I have done the following at the moment, which is static:
set "list=one two three four five"
(
for %%i in (%list%) do (
xcopy "C:\Users\Desktop\Source\Test.xlsx" "C:\Users\Desktop\Replica\%%i\testfolder" /Y
echo(%%i
echo(
)
)>copylog.txt
So, my question is basically who I do the listing of just the folders under "replica" and put those inside a list variable I can use in the code as already written. I only found sources where these are just saved within a separate .txt-file, but I just want to keep it inside the batch.
Any guesses on this one?
By the way: I experienced by saving a path just as a variable, I couldn't execute xcopy %source% %target% (even when having "%source%" or source = "Path"). What is the problem here?

You don't need to search the directories, put them into a variable and then iterate over the values in the variable. Just iterate over the directories
...
for /d %%i in ("C:\Users\Desktop\Replica\*") do (
xcopy /y "C:\Users\Desktop\Source\Test.xlsx" "%%~fi\testfolder"
...
The for /d will iterate over the indicated set of directories. In the xcopy command %%~fi is used to retrieve the full path of the directory for the current iteration.

Related

Parsing every file in submap recursively to output folder whilst maintaining relativity

I'm using the following batch code to convert all files in a certain directory if the target file doesn't already exist however I'm stuck at getting this to run through every submap and file within that (and keep the output relative with that submap)
So I currently use this:
for %%f in (input/textures/*.*) do ( IF NOT EXIST "ouput/textures/%%~nf.dds" (
"bin/ThempImageParser.exe" "input/textures/%%f" "ouput/textures/%%~nf.dds"
)
)
This works perfectly for a single folder (as was intended), it takes all the files in that specific folder, and passes them as arguments to my executable, which then outputs the file on the path of the second argument.
However this also contains a flaw (this is an additional problem though..) as it does not work if the output -folder- does not exist, so if possible I'd also want it to create the folder if need be.
I've found some batch documentation (I really don't have much experience with Batch) showing me a command called FORFILES and the /R parameter, however I couldn't adjust this so it'd keep the relative paths for the output too, it'd require string manipulation and I have no clue on how to do that.
So the result I'm after is something like this, it takes any file deeper than "input/textures/ for example:
input/textures/some/very/deep/submap/why/does/it/go/on/myfile.anyExtension
it should then take that file (and relative path) and basically change "input" with "output" and replace the file extension with .dds like this:
ouput/textures/some/very/deep/submap/why/does/it/go/on/myfile.dds
and pass those two strings to my executable.
#ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir\wherever\something"
FOR /f "delims=" %%a IN ('xcopy /y /L /s "%sourcedir%\*"') DO (
SET "destfile=%%a"
SET "destfile=!destfile:*%sourcedir%=%destdir%!"
IF /i "%%a" neq "!destfile!" (
FOR %%m IN ("!destfile!") DO IF NOT EXIST "%%~dpm%%~na.dds" (
ECHO MD "%%~dpm"
ECHO "bin\ThempImageParser.exe" "%%a" "%%~dpm%%~na.dds"
)
)
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
First, perform an xcopy with the /L option to list-only the individual fullnames of files that would be copied by the xcopy.
Assign each name found from %%a to destfile, then remove all characters before the source-directoryname from that filename, and replace that string with the destination directoryname.
This will yield the destination name for the file (with the original extension). The only exception will be the very last output line, which is a count-of-files report. Since this line will not contain the source directoryname, the replacement will not take place, so %%a will be the same as !destfile! - so we eliminate that.
Now assign the destination filename to a metavariable so we can select its various parts, and if the filename made from the destination drive and pathname, the name part of the original file and .dds does not exist, then make the destination directoryname and execute the imageparser, providing the desired output filename.
Note that these last two are ECHOed instead of being executed for testing purposes. Remove the ECHOes to actually perform the command.
Note that / is a switch-indicator, \ is a directory-separator.
Note that MD will report an error if the directory already exists. Append 2>nul to the end of the md command to suppress that error message.

Need a BAT file to copy & rename all files in specific tree

I need to create a .bat that runs through a multilayered directory... copying certain files that contain the following suffix: '.full.jpg' to save as '.jpg'
What I've tried:
copy /y "C:\Users\myname\Desktop\maindir\*.full.jpg" "C:\Users\myname\Desktop\maindir\*.jpg"
However, I cannot get it to work.
The .bat is located in the 'maindir' directory and ran from the terminal (cmd).
Here's an example scenario that maps closely to mine:
Existing Files:
C:\Users\myname\Desktop\maindir\a\a\picture1.full.jpg
C:\Users\myname\Desktop\maindir\a\a\picture3.full.jpg
C:\Users\myname\Desktop\maindir\a\b\picturea.full.jpg
C:\Users\myname\Desktop\maindir\a\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\b\a\foto.full.jpg
C:\Users\myname\Desktop\maindir\b\a\photo.full.jpg
C:\Users\myname\Desktop\maindir\b\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\b\c\pi2.full.jpg
Example Output Wanted:
C:\Users\myname\Desktop\maindir\a\a\picture1.full.jpg
C:\Users\myname\Desktop\maindir\a\a\picture1.jpg
C:\Users\myname\Desktop\maindir\a\a\picture3.full.jpg
C:\Users\myname\Desktop\maindir\a\a\picture3.jpg
C:\Users\myname\Desktop\maindir\a\b\picturea.full.jpg
C:\Users\myname\Desktop\maindir\a\b\picturea.jpg
C:\Users\myname\Desktop\maindir\a\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\a\b\pic1.jpg
C:\Users\myname\Desktop\maindir\b\a\foto.full.jpg
C:\Users\myname\Desktop\maindir\b\a\foto.jpg
C:\Users\myname\Desktop\maindir\b\a\photo.full.jpg
C:\Users\myname\Desktop\maindir\b\a\photo.jpg
C:\Users\myname\Desktop\maindir\b\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\b\b\pic1.jpg
C:\Users\myname\Desktop\maindir\b\c\pi2.full.jpg
C:\Users\myname\Desktop\maindir\b\c\pi2.jpg
I'd appreciate any help towards this as I haven't been able to do it yet. I will run across a directory structure whereby the top level directory will contain 15+ directories and each containing 20+ directories with 100+ files in each lowest directory.
Thanks.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=u:\Users\myname\Desktop\maindir"
FOR /r "%sourcedir%" %%a IN (*.full.jpg) DO (
FOR %%b IN ("%%~dpna") DO ECHO(COPY "%%a" "%%~dpnb.jpg"
)
GOTO :EOF
The inner for examines the drive-path-name only of the complete filename in %%a (ie. it drops the .jpg) and delivers the drive-path-name of that name (ie. drops the .full) to which you add .jpg and job done.
You would need to change the setting of sourcedir to suit your circumstances.
The required COPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(COPY to COPY to actually copy the files.

How to write a batch file to crop all the pdfs in a directory and store them in a new directory?

I'm totally unfamiliar with batch files but I'm pretty sure I need one for the task at hand:
I want to run pdfcrop for all the files in a particular directory and store the cropped files in a new directory. New directory is called 'croppedfiles' and if it doesn't already exist in the location where the pdfs are stored then such a directory is created and the output files are stored there.
I'd like the output files to have the same name as old files with the addition of '_cpp' at the end.
syntax for pdfcrop is just pdfcrop input.pdf output.pdf
Referring to the poor material you provided for this question - I mean only your for cycle quotation - I can only suggest a pair of tips: first you can narrow the group of files on which the for cycle is going to work, using a piped find ".pdf" command. Then you can use another nested for cycle to obtain the name of the file to be processed by pdfcrop and to set it as a variable to be used for the output path. Here is the example script:
for /f "delims=" %%g in ('dir ^"[set your desired path]^" ^| find
^".pdf^"') do ( set VAR=%%g for /f "tokens=1,2 delims=." %%m in
('!VAR!') do (mkdir "[chose your subdirectory name]" pdfcrop "!VAR!" "[subdirectory]\%%m[set
your additional characters].%%n" ) )
I hope it works, because I have been not able to test it.

Combining two FOR commands (/f /l) in a batch file

Okay guys, I am fairly new to working with batch files and I have two files I have previously created which are both working independantly.
I am looking to combine them but I still do not fully understand the FOR command. I was hoping someone could combine these two sets of code into one and if possible explain how the came up with the code they used from my two sources.
This file copies another file (in this case test.txt) to every subdirectory in a directory
FOR /R d:\ %%A IN (test.txt) DO copy d:\%username%\Desktop\Test\Resources\test.txt %%A
FOR /R h:\ %%A IN (test.txt) DO copy d:\%username%\Desktop\Test\Resources\test.txt %%A
This file copies and renames another file X amount of times (in this case 5) renaming each succesive copy in increments of 1.
For /l %%1 in (1,1,10) do (
copy test.txt test%%1.txt > nul
)
Basically I want the selected file (test.txt) to be copied from a set location to every subdirectory within a directory and then copied in each folder X amount of times and renamed with increasing values e.g.
test1.txt
test2.txt
test3.txt
etc.
Thankyou in advance.
This is actually very straight forward.
You already have functioning code that copies from the source to each subdirectory. In pseudo code: FOR (each directory) DO COPY source to target.
You also have code that can copy the file 10 times with incrementing names. You want to do this for each directory in the 1st step. So, again in pseudo code, it will look something like this:
FOR (each directory) DO (
COPY source to target
FOR (N=1 TO 10) DO COPY source to targetN
)
None of the syntax above is real, except that the parentheses after the DO are actually how you allow a batch FOR command to execute a block of multiple commands. (Actually there are other techniques to do this, but the parens work just fine.)
The part that you are missing is how to insert the incrementing number into the %%A target name. This is done by using FOR variable modifiers, as described at the end of the FOR documentation that you can access from the command line by typing HELP FOR, or FOR /?.
The modifiers allow you to deconstruct a file specification into its component parts. Note that the file doesn't have to physically exist, the file spec can still be broken down into the constituent parts.
%%~dpnA = drive:\path\baseName (no extension)
%%~xA = .extension, including the dot.
You've already got the incrementing number - I'm going to use %%N instead of %%1. So the full target will be the concatenation of the 3 components: %%~dpnA%%N%%~xA.
Putting it all together gives the full solution:
FOR /R d:\ %%A IN (test.txt) DO (
copy d:\%username%\Desktop\Test\Resources\test.txt %%A
FOR /L %%N IN (1 1 10) DO copy d:\%username%\Desktop\Test\Resources\test.txt %%~dpnA%%N%%~xA
)

Batch File to Delete Files in Folders

I have many folders in a directory that contain various files. Each filename begins with XXX_ where XXX could be the name of the folder the file is in. What I am needing to do is to go through all those folders and delete any file where XXX is the name of the folder that file is in.
Please have an eye out this question: Iterating through folders and files in batch file?.
I think this should help you.
Please let me know if you need further assistance.
EDIT #1
The joker character in DOS command line is *. Then, while searching a directory for certain files, you may consider your regular expression, that is, your XXX_, and complete it with *, this shall return only the files for which you're looking for.
This means that instead of *.zip pattern in one of the FOR loops given the linked question, your first FOR loop should contain your directory name, then take this variable concatenated with the * character to obtain only the files you're looking for.
For example, consider trying the following:
dir /s XXX_*.*
This should return only the files you're interested in, given the right folder name.
EDIT #2
Thanks for having precised your concern.
Here is a code sample that, I do hope so, should help. Now I know you say you have the looping correct, so that perhaps only piece of this code might be needed.
#echo off
setlocal enableextensions enabledelayedexpansion
for /F "delims==" %%d in ('dir /ogne /ad /b /s .') do (
for /F "delims==" %%f in ('dir /b "%%d\%%~nd_*.*"') do (
echo %%d\%%f
)
)
endlocal
This works and lists the files contained in subfolders from the current (.) folder.
I have tested it from the following folder:
C:\Docume~1\marw1\MyDocu~1\MyMusi~1
Where a 'XXX' folder is contained. This 'XXX' folder contains the following files:
Copy of XXX_blah.bmp;
XXX_blah.bmp;
XXX_1234.ppt;
XXX_textfile.txt.
From this structure, the output is:
C:\Docume~1\marw1\MyDocu~1\MyMusi~1\XXX\XXX_blah.bmp
C:\Docume~1\marw1\MyDocu~1\MyMusi~1\XXX\XXX_1234.ppt
C:\Docume~1\marw1\MyDocu~1\MyMusi~1\XXX\XXX_textfile.txt
I then suspect that putting a del instruction instead of an echo command shall do the trick. This means that to isolate the foldername itself from its path, you need to use the ~n instruction with your folder variable name like %%~nd, where your iterating folder variable name is %%d.
Furthermore, you could even use a parameterized batch file in the process, instead of hardcoding it, that is, if your 'set YourFolder =...' is part of your production code. This could look like:
#echo off
setlocal...
set root = %1
set root = %root:~1%
set root = %root:~0,-1%
...
endlocal
Instead of having '.' as pictured in my first FOR loop, your would replace it with "%root%" in order to consider your command line parameter instead of a hardcoded filepath.
I do help this helps, sincerely!
As Ron says, since the question is tagged "windows".
EDIT:
Ron's answer, which seems to have disappeared!, was to use del /s
EDIT2:
OK, it's valid only for file names, not for directories. For the directories you'd have to use something like sketched below.
Additional info: when you want to do the same thing recursively to files in a directory tree, and (unlike del) there's no command that already does the traversing for you, you can use the /R option of the for command.
To see the for command's docs, do e.g. start "for-help" cmd /k for /?.
Cheers & hth.,
– Alf
cd C:\"foldername"
del /s XXX_"*"
cls
exit

Resources