Batch cmd MKDIR folder with a name including symbol - batch-file

I would like use command batch to create list folder.
But the name of folder include symbol characters, I don't know how to use cmd batch
Ex: I would like create list folder
01.DOCUMENT
02.SOURCE
03.DESIGN
04.TEST
05.REPORT
06....
Input: Input root-directory(strfolder)
Then example use: mkdir %strfolder%\ (+ name folder 01.Ducment,...) but I don't know use
My current code:
#echo off
cls
set /p folderName=Enter project name:%=%
#echo %folderName%
SET mypath=%~dp0
rem echo %mypath:~0,-1%
set folder=%mypath%%folderName%
if exist %folder% (
echo "Folder already exists"
) else (
mkdir %folder%
rem mkdir %folder%\%1 %RELEASE% --> this line don't know how :D
echo %folder%\%^1%
)
pause

You'd need to quote your target if it contains symbols:
mkdir "%folder%"
(md is the same as mkdir)
Also:
mkdir "%folder%" 2>nul
will create the directory; the 2>nul suppresses the error message.
%release% appears from nowhere. You don't say what it is or where it comes from; then you REM it anyway. No iea of what is happening there.
Now if your directory-names are in a file then
for /f "delims=" %%i in (filename.txt) do echo %%i
should show you the names. If you want to create subdirectories using these names then
for /f "delims=" %%i in (filename.txt) do echo MD "%folder%\%%i"
should do that for you - well, would ECHO the command; remove the ECHO keyword to actually make the directory.
Note that virtually any character would be happy so long as it remains in the metavariable %%i used as a loop-control. Some less-frequently-used characters can present a problem within an ordingary %variable%.
If your data contains parentheses, then the parser may become confused about whether a parenthesis is part of the command or the data. Best to avoid parenthesised constructs if that is the case.

Related

How to properly use rename (ren) in Batch

I am trying to rename every image in a directory to add the date that each file was created, however, I keep either getting "invalid syntax" or "A duplicate file name exists, or the file cannot be found"
I am running Windows 10, and accessing the images off a flash drive (hence the short file path). I tried having all the code in one for-loop, when that didn't work I tried using batch functions, no dice. I did see someone mention on another thread to use delayed expansion, I would be up for using this if someone could give a better explanation than the /? command.
#echo off
REM batch file is placed in top of F drive, same as "images 2017+"
cd "F:\images 2017+"
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~nF" "%%~tF"
goto :eof
:renER
cd "F:\images 2017+"
pause
echo %1
echo %2
rename %1.jpg %1_%2.jpg
pause
goto :eof
:end
For every .jpg file in "images 2017+", the date which that file was created would be stuck onto the end after a space.
thisIsMyFile.jpg made at 5-13-2017, would become thisIsMyFile 5-13-2017.jpg
Current output
EDIT:
I am CDing into the same directory as the images are, then using the passed variables to locate the correct image (The date is one of the passed variables, and shows up in the echo command).
I notice that you only want the date, not the time so you can do that as follows using your existing Call to a label, There is also no need to use FOR /R in this case so I'll use a normal for loop:
#echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
CALL :RenER "%%~fA" %%~tA
)
GOTO :eof
:RenER
PAUSE
ECHO %1
ECHO %2
SET "_tmp=%~2"
SET "_tmp=%tmp:/=-"
REN "%~1" "%~n1_%_tmp%%~x1"
PAUSE
GOTO :eof
Notice how above we are dropping the Time off immediately by not wrapping it in quotes since you don't want that to be part of the file name.
You can also forgo the call to a label entirely without needing delayed expansion by using a second loop, as a matter of preference I think this is quite a bit cleaner!
#echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
FOR /F "Tokens=1-3 Delims=/ " %%a IN ('echo.%%~tA') DO (
PAUSE
ECHO.%%~fA
ECHO.%%~tA
REN "%%~fA" "%%~nA_%%a-%%b-%%c%%~xA"
PAUSE
)
)
this is nice and clean and with a minor edit we can paste it directly into the CMD Prompt which is nicer still This is because we are not using DelayedExpansion, Calling a Label, or using Temp variables so by changing the %%s to %s, we can then Paste this directly into the CMD Line which is often more convenient when doing these sorts of operations:
This Multi-line will do just fine to be pasted into CMD directly:
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO #(
PAUSE
ECHO.%~fA
ECHO.%~tA
REN "%~fA" "%~nA_%a-%b-%c%~xA"
PAUSE
)
)
or, as a single line to paste into CMD if you prefer:
FOR %A IN ("F:\images 2017+\*.jpg") DO #( FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO #( PAUSE& ECHO.%~fA& ECHO.%~tA& REN "%~fA" "%~nA_%a-%b-%c%~xA"& PAUSE ) )
no need to cd anywhere. ren takes a full path/filename for source - just the destination must be a filename only. So ... do call :renER "%%~fF" "%%~tF" is fine (no need to snip the extension and add it again later). In the subroutine reformat the time to a valid string and reassemble the destination file name:
#echo off
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~fF" "%%~tF"
goto :eof
:renER
pause
echo %1
echo %2
set "string=%~2"
set "string=%string::=-%"
set "string=%string:/=-"
ECHO rename "%~1" "%~n1_%string%%~x1"
pause
goto :eof
:end
NOTE: I disarmed the rename command. Remove the ECHO after troubleshooting, if it works as intended.
#Stephan's answer is probably the best approach. But if you want to change directories ...
The windows shell has a working drive/volume, and on each drive/volume a current working folder. cd changes the working folder on a disk; to change the working folder on a drive (which is not the working drive) and to make that drive the working drive, you need to use cd /d, in this case cd /d "F:\images 2017+".
(A plain cd in this instance changes the working folder on F:\, but if your working folder is on C: -- as I'm guessing is the case -- it will not be changed.)
Assuming command extensions are enabled, you should also be able to use pushd and popd. pushd behaves like cd /d but also saves your previous location; popd returns you to that previous location. (And IIRC pushd will accept UNC paths.)
So at the beginning of your script, pushd "F:\images 2017+", and at the end popd.
I tend to favor pushd/popd over cd because invocations can be nested. So you can do things like
(assume working directory is C:\Users\IoCalisto):
pushd "F:\images 2017+"
(working directory is now F:\images 2017+)
pushd "Z:\images 2015-2016"
(working directory is now Z:\images 2015-2016)
popd
(working directory is now F:\images 2017+)
popd
(working directory is now C:\Users\IoCalisto)
... with this approach, your scripts will have fewer "side effects" and be more modular, or at least modularizable.

Create Folder and SubFolder based on file name using batch file

Coding is not my speciality but I have come across a problem and google search has guided me to using batch file process in solving it. Essentially I have a couple of thousands of files that need to be moved into folders and they have a very simple file structure, listed below:
UK--London--Filename.pdf
UK--London--Filename2.pdf
UK--Manchester--Filename3.pdf
UK--Liverpool--Filename4.pdf
UK--Chester--Filename5.pdf
I would like the script to:
1. Pick up the first "--" check if the folder exists, if not create it
2. Pick up the second "--" check if the folder exists, if not create it
3. As there might be more than two "--", ignore the rest
4. Move file into the subfolder
To that end, the output should be some like (note "FILETEST" is the folder I am using to test the script):
C:\FILETEST\UK\London\UK--London--Filename.pdf
C:\FILETEST\UK\London\UK--London--Filename2.pdf
C:\FILETEST\UK\Manchester\UK--Manchester--Filename3.pdf
C:\FILETEST\UK\Liverpool\UK--Liverpool--Filename4.pdf
C:\FILETEST\UK\Chester\UK--Chester--Filename5.pdf
I have had an attempt to re-using a script from another question in stackoverflow (Batch create folders based on part of file name and move files into that folder). I understand that it would not do exactly what I need, but cant seem to get any output.
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\FILETEST"
PUSHD %sourcedir%
FOR /f "tokens=1*delims=--" %%a IN (
'dir /b /a-d *.*.*'
) DO (
ECHO MD %%a
ECHO MOVE "%%a.%%b" --\%%a\
)
POPD
GOTO :EOF
Apologies for any headaches caused, I am hoping this is a simple one to solve.
Thank you,
Panos
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\FILETEST"
PUSHD %sourcedir%
FOR /f "tokens=1,2*delims=-" %%a IN (
'dir /b /a-d *--*--*.*'
) DO if "%%c" neq "" (
ECHO MD "%%a"
ECHO MD "%%a\%%b"
ECHO MOVE "%%a--%%b--%%c" ".\%%a\%%b\"
)
POPD
GOTO :EOF
Read the directory list of files in the current directory, (/a-d = no directorynames) that match *--*--*. Tokenise so that %%a acquires the part before the first --sequence, %%b the second and %%c the remainder.
If %%c is not empty then make the directories ".\%%a" and ".\%%a\%%b" (quoted because any spaces in the name would otherwise be seen as "create two directories") then move the file, again quoted for the same reason.
Note that each character individually between delims= and the close-quote is a delimiter - a delimiter-string is not supported. Consequently, this code will pick up - as well as --- and any other sequence of - and try to process it. You could gate the create/move further by adding if exist "%%a--%%b--%%c" directly after the if "%%c" neq ""before the (.
The md will create a directory if the target name does not already exist, and produce an error-message if it already exists. To suppress the error message, append 2>nul to the md lines.

Batch Finding and displaying duplicate strings in file names

I have a question. Is it possibile in batch language to search in folder a part of name that is same like another file and display it.For example i got folder with files :
ggggggsss.mp3
ddddddeee.mp3
ddddddff.mp3
ssssssddd.mp3
aaaaasssss.mp3
11111ssdas.mp3
11111dddd.mp3
...
I need to display in cmd only names of files
ddddddeee
ddddddff
and
11111ssdas
11111dddddd
Because the first six letter are the same. Could someone help me with this problem?
Save this script to test.bat and run from open Cmd Prompt. Replace dir value with path to your folder with .mp3 files:
#echo off
setlocal enabledelayedexpansion
set "dir=%userprofile%\music"
set "pattern1=dddddd" & set "pattern2=11111"
pushd "%dir%"
FOR %%G IN (*.mp3) DO ( set song=%%G
if "!song:~0,6!"=="%pattern1%" echo %%G)
echo/
FOR %%G IN (*.mp3) DO ( set song=%%G
if "!song:~0,5!"=="%pattern2%" echo %%G)
popd
exit /b
See also Extract Substrings.

Batch script that moves each file in a folder into their own folders named after the file?

So if I have
/folder/file1.txt
/folder/file2.jpg
/folder/file3.py
I want to create
/folder/file1/file1.txt
/folder/file2/file2.jpg
/folder/file3/file3.py
I have this batch file (be careful where you run it), which mostly works but if there is whitespace in the file name, the folder name will only be named up until the whitespace and so the file won't be moved inside of it.
Also, I only got it to work by arbitrarily putting the word "Folder" or some random string at the end of the folder name, if I exclude that, for some reason it won't work. I'm on windows 7.
#echo off
for /f %%a in ('dir /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a"
)
goto :EOF
:func
set file=%~1
set dir=%file% Folder
md "%dir%" Folder 2>nul
move "%file%" "%dir%"
goto :EOF
Any ideas on how to address the whitespace/name issues? Thanks in advance.
#echo off
for /f "usebackq delims=?" %%a in (`dir /a-d /b`) do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a"
)
goto :EOF
:func
set file=%~1
set dir=%file% Folder
md "%dir%" Folder 2>nul
move "%file%" "%dir%"
goto :EOF
By setting the delims=? you are saying that your delimiter is a ? to split up a string, instead of the whitespace character, which allows you to read full file names with spaces in them. Usebackq means that you instead use ` around the command to be ran, which to me, just makes it more logical to read and understand "Hey, I'm actually executing this string."
To avoid problems with spaces in paths/file names, double quote all the references to them.
The reason for having to include a string at the end of the folder in your code is you are trying to create a folder with exactly the same name that the file (in your code, you are not removing the extension), and you can not have two elements (files or folders) inside a folder with the same name.
#echo off
for %%a in ("c:\folder\*") do (
if not "%%~fa"=="%~f0" (
if not exist "%%~dpna\" echo md "%%~dpna"
if exist "%%~dpna\" echo move /y "%%~fa" "%%~dpna"
)
)
For each file in the indicated folder
if the file is not the batch file
if not exist a folder with the same name that the file, create it
if the target folder exist, move the file to the folder
%%~fa = full path of the file being processed
%~f0 = full path of the batch file
%%~dpna = drive, path, and file name without extension of the current file being proccesed
In this code, the reason for the third if is to check if the possible previous folder creation has failed. If you have a file with no extension, you will not be able to create the folder, as it will have exactly the same name as the file and this is not allowed.
Code includes echo commands before md and move to show what will be executed. If the output is correct, remove the echo to make it work.

Iterating through folders and files in batch file?

Here's my situation. A project has as objective to migrate some attachments to another system.
These attachments will be located to a parent folder, let's say "Folder 0" (see this question's diagram for better understanding), and they will be zipped/compressed.
I want my batch script to be called like so:
BatchScript.bat "c:\temp\usd\Folder 0"
I'm using 7za.exe as the command line extraction tool.
What I want my batch script to do is to iterate through the "Folder 0"'s subfolders, and extract all of the containing ZIP files into their respective folder.
It is obligatory that the files extracted are in the same folder as their respective ZIP files. So, files contained in "File 1.zip" are needed in "Folder 1" and so forth.
I have read about the FOR...DO command on Windows XP Professional Product Documentation - Using Batch Files.
Here's my script:
#ECHO OFF
FOR /D %folder IN (%%rootFolderCmdLnParam) DO
FOR %zippedFile IN (*.zip) DO 7za.exe e %zippedFile
I guess that I would also need to change the actual directory before calling 7za.exe e %zippedFile for file extraction, but I can't figure out how in this batch file (through I know how in command line, and even if I know it is the same instruction "cd").
EDIT #1
I have already received some tips on ServerFault to the same question. Please see the answers at this link.
However, it extracted from the root (C:), and not from the given in parameter folder.
Anyone has an idea?
EDIT #2
It seems that batch script doesn't handle folder and file names containing a space character adequately. Can anyone confirm what I think?
EDIT #3
I need it to be fully recursive, since I don't know the directory structure against which this will be used.
EDIT #4.a
With #aphoria's solution, I'm almost there! The only problem is that it takes let's say File5.zip, retrieve the filename only to get File5, creates a subfolder File5 and extract the File5.zip to File5 subfolder, then, it wants to create a File5 subfolder in Folder 1, where it should instead want to create File1 subfolder, to stick with my example.
EDIT #4.b
As required, here's the code as it currently look:
#echo off
setlocal enableextensions enabledelayedexpansion
rem
rem Display instructions when no parameter is given.
rem
if "%1" equ "" (
echo Syntaxe : od.bat ^<directory mask>^
echo Exemple : od.bat *
goto :Eof
)
rem
rem Setting the PATH environment variable for this batch file for accessing 7za.exe.
rem
path=c:\temp;%PATH%
rem
rem Removing quotes from the given command line parameter path.
rem
set root=%1
set root=%root:~%1
set root=%root:~0,-1%
rem Searching directory structure from root for subfolders and zipfiles, then extracting the zipfiles into a subfolder of the same name as the zipfile.
for /F "delims==" %%d in ('dir /ogne /ad /b /s %root%') do (
echo Traitement du dossier : "%%d"
for /F "delims==" %%f in ('dir /b "%%d\*.zip"') do (
rem Getting filename without extension.
set subfolder=~n%f
mkdir "%%d\%subfolder%"
rem Extracting zipfile content to the newly created folder.
7za.exe e "%%d\%%f" -o"%%d\%subfolder%"
)
)
:Eof
endlocal
Ideas anyone?
My guess is that it digs one directory hierarchy at a time. Here's the deal. Consider we have a Folder A in Folder 1 (Folder 1\Folder A), then, it searches from Folder 1 through Folder 5, and comes back to Folder 1\Folder A, where the %subfolder% variable sticks with its last value.
Anyone's help is gratefully appreciated.
I'm not very familiar with the 7zip command-line options, so you will need to figure out the exact command for that, but the script below will take a fully specified path (spaces allowed) and print out the the folder name and .zip files contained within it.
#ECHO OFF
REM
REM Remove the double quotes from the front and end of the root path
REM
SET ROOT=%1
SET ROOT=%ROOT:~1%
SET ROOT=%ROOT:~0,-1%
ECHO %ROOT%
FOR /F "DELIMS==" %%d in ('DIR "%ROOT%" /AD /B') DO (
ECHO %%d
FOR /F "DELIMS==" %%f in ('DIR "%ROOT%\%%d\*.zip" /B') DO (
ECHO %%f
)
)
Run it like this:
MyScript.CMD "c:\temp\usd\Folder 0"
You should get output similar to this:
Folder A
File 1.zip
File 2.zip
Folder B
File 1.zip
File 2.zip
UPDATE
The code below will extract Folder A\File 1.zip to a new folder Folder A\File 1.
A few things to keep in mind:
In the first FOR loop, you need to have %ROOT% enclosed in double quotes to handle folders with spaces in the name.
Since you're SETting a variable inside the second FOR, you need to put SETLOCAL ENABLEDELAYEDEXPANSION at the beginning. Then, reference the variable using ! (for example, !subfolder!) to force expansion at runtime.
This line of your code set subfolder=~n%f should be this set subfolder=%%~nf
I put ECHO in front of the MKDIR and 7za.exe commands to test. Once you are sure it is doing what you want, remove the ECHO statement.
Here is the code:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM
REM Remove the double quotes from the front and end of the root path
REM
SET ROOT=%1
SET ROOT=%ROOT:~1%
SET ROOT=%ROOT:~0,-1%
ECHO %ROOT%
REM Searching directory structure from root for subfolders and zipfiles,
REM then extracting the zipfiles into a subfolder of the same name as the zipfile.
FOR /F "delims==" %%d IN ('dir /ogne /ad /b /s "%ROOT%"') DO (
ECHO Traitement du dossier : "%%d"
FOR /F "delims==" %%f IN ('dir /b "%%d\*.zip"') DO (
REM Getting filename without extension.
SET subfolder=%%~nf
ECHO mkdir "%%d\!subfolder!"
REM Extracting zipfile content to the newly created folder.
ECHO 7za.exe e "%%d\%%f" -o"%%d\!subfolder!"
)
)
ENDLOCAL

Resources