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.
Related
My university is using a proprietary system that outputs data in a very specific way in which each "module" is output into folders following the structure (4 digit numeral) - (name of module)
ex: 5574-CHEM104
I need to remove the name and hyphen so that only the numeral remains:
5574-CHEM104 > 5574
The problem is that there's thousands of these folders and there's no way I could do it by hand. I'm having difficulty trying to automate the process, so if anyone could at least point out a command I could look into it would help immensely
I've tried the REN command, putting "REN 5574-CHEM104 5574", but it only works for one folder. There's thousands of folders, each with different numerals, under "CHEM104", for example, and I need for the program to rename the folder no matter the original name into the first 4 original numerals, which I can't figure out. Thanks!
#ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
FOR /f "delims=" %%e IN (
'dir /b /ad "%sourcedir%\*" '
) DO FOR /f "delims=-" %%o IN ("%%e") DO ECHO REN "%sourcedir%\%%e" "%%o"
)
GOTO :EOF
Always verify against a test directory before applying to real data.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the directories.
Using a list of the directory-names, names only (/b) and directories only (/ad), tokenise the name using - as a delimiter and execute the rename using the token assigned to %%o (default is first token)
I was trying to move my files(books) based on it's author name.
For example:
[author] Title 1.pdf
[author2] Title A.pdf
I've found a batch script for this
#echo off
for %%i in (*) do (
if not "%%~ni" == "organize" (
md "%%~ni" && move "%%~i" "%%~ni"
)
)
It works but it made each folder for each files, what I want to do is create folder by author names and move it there.
Note: All author name have "[]" in it's file name but the folder created only has author name without "[]".
Please help, I have 4000+ files I need to sort.
The following script uses a for /F loop to split the file names which are gathered by the dir command:
#echo off
for /F "tokens=1* delims=[] eol=]" %%I in ('dir /B /A:-D-H-S "[*]*.pdf"') do (
ECHO md "%%I" 2> nul
ECHO move "[%%I]%%J" "%%I\"
)
The 2> nul portion suppresses error messages in case the directory to create already exists.
After having tested for the correct output, remove the upper-case ECHO commands from the md and move command lines. To avoid multiple 1 file(s) moved. messages, append SPACE + > nul to the move command line.
The trailing \ at the destination of the move command is intended to force it to point to a directory. Imagine the destination directory could not be created for some reason (for example, lack of access privileges), the destination without the \ is interpreted as a new file name in the working directory, leading to unintentional renaming; with the \ the move command expects an existing directory, and if not found an error arises.
Besides the fact that your code did not attempt to split the file names as needed, there is one additional problem: the && operator lets the following command execute only in case of success of the former one; so when md failed, move does not run. For example, you have got two files with the same author, so when iterating the second one, the destination directory already exists since it has been created in the previous iteration, so md fails and the respective file is not moved. Therefore you should have used the unconditional & operator.
I have a batch file that gets run by the user typing:
usercompile filename
usercompile is a batch file that does this:
copy /y %1.txt lib\incoming_file.txt
and then starts the compiler:
compiler.exe
The compiler has the "incoming_file" name hard-coded into linked source (this can't be chaged), so the current method is simply to copy the user file in and rename it to the known name and run the compiler.
I'd like to present the user with a list of files that are generated when a batch file is run, then the batch file would copy the selected file in, rename it (just like is done now).
So it would look like this:
Please choose a file to compile:
1) matthews_build
2) marks_build
3) lukes_build
and then the user would type 1 or 2 or 3 (in this case) and press enter. The batch file would copy that file to the known file name and launch the compiler. The one good thing is that the files that need to be listed all have a unique extension (.jal).
Any ideas?
I changed my approach and consider my previous answer a bad practice: re-listing the files with a second dir command unnecessarily reads the disk again, not to mention the rare but possible case if a file is added/removed between the 2 dir's and makes the whole thing unreliable.
Based on this brilliant solution I did a possible implementation with dynamic array:
#echo off
set /a counter=0
setlocal enabledelayedexpansion
FOR /f "delims=|" %%i IN ('dir /b /on "yourpath*.jal"') DO (
set /a counter+=1
rem echo !counter!^) %%~ni
set FileList[!counter!]=%%~ni & rem This is an array element, a dinamically created variable
)
rem Iterate through variables:
FOR /l %%i IN (1,1,!counter!) DO (
echo %%i^) !FileList[%%i]!
)
set /p option="Choose an option: "
echo !FileList[%option%]!
endlocal
This makes the file list available for any number of following commands.
One possible solution is to list all .jal files and give them an option number, store the result, and based on user input, look up the file based on the option number. As I know no way of storing such a result in memory (no array/hash table data type), only in a file, if a file can not be used, then the listing should be repeated in a deterministic way so that if we re-assign the option numbers, we get the same result. We can do it ensuring alphabetical ordering.
Here is one implementation:
BLOCK 1
setlocal enabledelayedexpansion
FOR /f "delims=|" %%i IN ('dir /b /on "yourpath\*.jal"') DO (
set /a counter+=1
echo !counter!^) %%~ni
)
endlocal
The nested dir command ensures alphabetical ordering (reference.)
A remark why I put a pipe (|) as a delimiter: if you don't define a delimiter, the default space will be used. If your file name contains space then it would be truncated. So I picked a character that is not valid in file names ensuring the whole file name is returned.
Now if you get a number from the user by this:
set /p option=Choose your option:
after this command (evaluating and possibly re-requesting the input) to do a lookup for the file you can repeat BLOCK 1 but replace the echo line with examining the option like this:
if !counter! == %option%
and put those commands in the if block to do whatever you want to do with the file (for debugging, put back the echo command).
I am very new to coding and bulk processes but i am looking for a command line SPECIFICALLY for windows command prompt and i am wondering if such a thing exists. So I have a folder containing 111 subfolders, with each subfolder containing between 20 and 40 png image files. Each subfolder is named 001-111 accordingly and the png files are ordered how i want them, however i am looking for a command line that would be able to quickly and efficiently name all the pngs in the folders to the name of the folder followed by the png number in brackets
e.g. for folder 037, i would want the png's to be renamed to: 037(1), 037(2), 037(3) etc...
I am hoping for the best although i am unsure such a code may not be possible or be simply done.
Also if you come up with a code that achieves this process, it would be great if you could reply with the simple command line that i could use rather than a full explanation because i am new to coding and far from fluent with the language or terms or how things work. I know this same process can be achieved by going select all>rename (ctrl a>f2) and renaming to the folder name however i need to use this process frequently and dont want to have to open each folder, i would rather have a command line for cmd that would do it swiftly
Thank you and a simple answer would be greatly appreciated
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "parentdir=u:\parent"
FOR /l %%a IN (1001,1,1111) DO (
SET dir=%%a&SET "dir=!dir:~1!"
FOR /f "delims=" %%i IN ('dir /a-d /b "%parentdir%\!dir!\*.png" 2^>nul') DO (
ECHO REN "%parentdir%\!dir!\%%~nxi" "!dir!(%%~ni)%%~xi"
)
)
GOTO :EOF
Test results:
Starting directory :
u:\parent\001\1.png
u:\parent\037\1.png
u:\parent\037\2.png
u:\parent\111\999 with spaces in name.png
Script response
REN "u:\parent\001\1.png" "001(1).png"
REN "u:\parent\037\1.png" "037(1).png"
REN "u:\parent\037\2.png" "037(2).png"
REN "u:\parent\111\999 with spaces in name.png" "111(999 with spaces in name).png"
Obviously, you'd need to replace the value assigned to parentdir with your actual target directory name.
The script will report the renames it proposes to do. To actually invoke the rename remove the ECHO keyword.
I would create a batch file like so:
renamepng.bat:
cd %%1
if ERRORLEVEL 1 goto end
for %f in *.png do mv "%f" "%%1(%f).png"
cd ..
:end
This will attempt to cd to the directory name provided on the command line, abort if that fails, then rename all the .png files and return to the previous directory
then call it like so:
for %d in ??? do call renamepng.bat %d
which will loop through all 3-character file and directory names in the current directory, can call the batch file on each one. Using call instead of just the batch file name causes execution to return to the loop when the batch finishes.
Is there a way with a batch file to instantly MOVE a file when it's downloaded into Directory A into Directory B based on a variable in the file's name?
I have a file naming convention that looks like this: Photo-87654321-1.jpeg
The 87654321 part is the variable. Now, with if statements and such, I can locate the directory, or if it doesn't exist, create the directory and then place the image in there. The problems I'm having is: a) copying that variable string from the file name, b) running this script every time a file is moved into Directory A.
You haven't given enough details about what you want to do with the file when you find the variable number, so I can only improvise.
This script will get the variable name from the files in C:\DirectoryA and then move them into a folder with that name.
:LOOP
for /f "tokens=2 delims=-" %%a in ('dir /b /a-d "C:\DirectoryA"') do (
md "%%~na"
move "%%a" "%%~na"
)
goto :LOOP
This should give you enough details to tweak to your needs, but if you need anything more specific please provide more details.
Note: Given that you want to move files as soon as they are put in DirectoryA, this is on an infinite loop, so you may want to watch your CPU.