I am trying to write a batch script to rename multiple folders.
I would like to do something like below:
Rename all folders under the "Workspace" folder by appending my name in the end of the folder names
For example, rename:
Workspace/RiskFolder
Workspace/PNLFolder
to:
Workspace/RiskFolder_myname
Workspace/PNLFolder_myname
Is this possible?
You could use for to loop through each directory and rename it like so:
for /D %%f in (C:\path\to\Workspace\*) do rename "%%f" "%%~nxf_myname"
I tested this on Windows 7, but it should work at least as far back as with Windows XP.
What that does is this: for each directory in the path (within parenthesis), assign the directory name to the variable %%f, then rename the directory %%f to the name in the format you want (with your name attached). %%f holds the full pathname, which is fine for the first argument to the rename command, but for the second argument, we only want the filename+extension, thus the ~nx modifier prepended to our variable name.
By the way, when using this for loop on the command line (rather than part of a batch file) you only want to use one % instead of %% for your variable name. E.g. for %f in... instead of above.
See the following references from Microsoft for more details:
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/for.mspx?mfr=true
You can use the following command within your batch file:-
for /F "usebackq tokens=*" %%a in (`dir /ad /b %1`) do ren %1\%%a %%a%2
This is the DOS 'for' command, which iterates over given set of items, and for each element in the set, performs the given action. For the given requirement, we need to do the following:-
1) Accept name of folder which contains sub-folders to be renamed(in your example, it is Workspace).
2) Accept the string to be appended to the end(in your example, it is your name).
3) List the names of sub-folders in the folder.
4) Rename by appending the string to original name.
Let's see how this for command accomplishes that. The format of 'for' command used here is:-
for /F ["options"] %variable IN (`command`) do command [command-parameters]
The command here assumes that the required parent directory name and string to be appended are passed on as command line parameters. These are represented by %1 and %2 (first and second parameters).
To enable us to issue a dos command to be evaluated, we need to use the /F option. The option string is :-
"usebackq tokens=*"
usebackq specifies backquouted string is a command to be evaluated.(Note that the dir command is enclosed within backquotes(`) )
tokens=* means to consider each line as a single token and pass to the command
To list the sub-directories in parent directory, we use the command:-
dir /ad /b %1
/ad displays only directories (ignores files)
/b displays it in bare format, i.e., only names are returned and date, time and other info are not.
%1 is the command line variable referring to parent directory.
%%a is the variable which receives the sub-directory name in each iteration. Double percentage symbol is required since we use it in a batch file, otherwise, just one is required (like %a)
Finally, we specify the action to be performed:-
ren %1\%%a %%a%2
%1\%%a constructs absolute path to sub-directory
%%a%2 append second command line parameter to original name
For more info on for command, type following in a command prompt:-
for /?
For another usage example, refer Loopy loops: The DOS way
No need for a batch file. This will work from the command line
for /d %D in ("Workspace\*") do ren "%D" "%~nxD_myName"
If you do use a batch file, then %D must become %%D
If there is no need to perform folder/file renaming with a batch file, you can also use the Bulk Rename Utility for Windows. Check this: http://www.bulkrenameutility.co.uk/Download.php
For /D %%f in (*) do rename "%%f" "%%fWhatEverNameYouLike"
pause
The pause is to see it! Make a cmd of it and put it in the folder that you want to rename all it's subfolders! They'll rename to each one folders name, plus the WhatEverNameYouLike
Related
I have a list of csv files with date and time appended like "Account_data_yyyymmdd.csv" which are added daily along with its timestamp to source dir .I have to identify latest file ie.'Account_data_2020_08_05.csv' and set the value in variable . so i can pass it as argument
Files in source dir
Account_data_2020_08_05.csv
Account_data_2020_08_04.csv
Account_data_2020_08_03.csv
I have to find the recently placed file based on its timestamp & pass it as input for calling another batch process. Highlighted text is the argument to batch file.How to find latest file based on its timestamp and pass it as argument for
echo "start"
call process.bat "C:\CSVDataLod" AccntDataloadprocess ***"dataAccess.name=C:\SourceDir\ Account_data_%year%_%month%_%date%.csv"***
That's surprisingly easy. Use dir with the /on switch to sort by name (see dir /? for that switch and the others I used, if you are not familiar with them) and put a for /f loop around to capture the output. The following code sets the variable %last% to each line of the output, keeping the last one only:
for /f "delims=" %%a in ('dir /a-d /on /b Account_data_*.csv') do set "last=%%a"
echo %last%
The easiest and fastest method to get name of CSV file with newest date in file name is using command DIR with option /O-N to get the CSV file names output ordered by name in reverse order. The file name with newest name is output first by DIR in this case. The output of DIR has to be captured and processed with FOR. The FOR loop is exited after running the other batch file with first file name output by DIR.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FileFound="
set "FileNamePattern=Account_data_20??_??_??.csv"
if /I "%~x1" == ".csv" set "FileNamePattern=%~nx1"
for /F "delims=" %%I in ('dir "C:\SourceDir\%FileNamePattern%" /A-D /B /O-N 2^>nul') do (
echo Processing file %%I ...
call process.bat "C:\CSVDataLod" AccntDataloadprocess "dataAccess.name=C:\SourceDir\%%I"
if /I not "%~1" == "/A" goto EndBatch
set "FileFound=1"
)
if not defined FileFound echo There is no file "%FileNamePattern%" in directory "C:\SourceDir".
:EndBatch
endlocal
I recommend to open a command prompt and run
dir "C:\SourceDir\Account_data_20??_??_??.csv" /A-D /B /O-N
Then you know which lines are processed by FOR. Next run
dir "C:\SourceDir\Account_data_20??_??_??.csv" /A-D /B
dir "C:\SourceDir\Account_data_20??_??_??.csv" /A-D /B /ON
to see how DIR outputs the CSV file names without specifying a specific order resulting in printing the file names as returned by the file system and explicitly ordered by name in alphabetical order instead of reversed alphabetical order.
The file system NTFS returns a list of file names matched by a wildcard pattern in local specific alphabetic order while FAT file systems like FAT16, FAT32, exFAT return the file names not ordered at all. In real all file systems return the file names in order as stored in the table of the file system. The file systems use just different methods on how to add a file name to table of the file system. The FAT file systems append a new file name always at end of the table of a directory while NTFS inserts a new file name in table of a directory using a local specific alphabetic sort algorithm.
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background with %ComSpec% /c and the command line within ' appended as additional arguments.
Edit:
The batch file can be run with /a or /A as argument to process all CSV files matching the wildcard pattern from newest to oldest instead of just the newest. The batch file can be also run with name of a .csv file in source directory to process this specific CSV file instead of the newest CSV file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
dir /?
echo /?
endlocal /?
for /?
goto /?
setlocal /?
I must be missing something obvious. The current working directory is C:\src\t\zf. The DIR command should get the .csv files from the parent directory, C:\src\t. I was expecting %~dpnxa to output the full path to the files. But, it does not. It uses the current working directory path and appends the filename. What am I missing?
echo off
cd
C:\src\t\zf
for /f "delims=" %a in ('dir /b "..\*.csv"') do (echo "%~dpnxa")
"C:\src\t\zf\Aliases.csv"
"C:\src\t\zf\c.csv"
"C:\src\t\zf\iplist.csv"
"C:\src\t\zf\my.csv"
"C:\src\t\zf\original.csv"
"C:\src\t\zf\original2.csv"
"C:\src\t\zf\original3.csv"
"C:\src\t\zf\output.csv"
"C:\src\t\zf\rearrange.csv"
"C:\src\t\zf\rearrange-out.csv"
The "problem" is what the for replaceable parameter contents refer to:
In a simple for command, the replaceable parameter refers to a file/folder.
In a for /f the replaceable parameter refers to a text line.
And you are in the second case. Your for /f is processing text lines. As you are using a dir /b you only get the name and extension of the files, without any path that is only included when the /s is also used.
As the for replaceable parameter only contains a string (the file name, but just a string), any operation trying to obtain a drive or path (%~dpa) not present in the string will use the current directory as information source.
You could try with
for %%a in ("..\*.csv") do (echo "%~fa")
Assuming I have a bunch of sqlcmd commands in .cmd files, order alphabetically e.g.:
01.setup.cmd
02.version1.cmd
03.version2.cmd
04.version3.cmd
how could one sequentially execute these in correct order with another .cmd file?
On windows:
for /F "tokens=*" %a in ('dir /b *.cmd') do call "%a"
This just loops over the result of dir /b *.cmd calling each in turn.
explanation from the docs:
FOR /F processing of a text file consists of reading the file, one
line of text at a time and then breaking the line up into individual
items of data called 'tokens'. The DO command is then executed with
the parameter(s) set to the token(s) found.
So my command says:
"tokens=*" don't give me individual tokens, give me the whole line as one hit
%a - name the line variable %a (note: it'll needs to be escaped as %%a if you're putting it in a batch file
('dir /b *.cmd') This is the input that it'll loop over. A bare directory listing for all .cmd files
then what I want it to do. Call the command %a.
If I didn't add the tokens bit it would work fine until you find a space in the file names.
I have to run a tool(.exe) that is stored in a particular folder.(Say C:\Temp)
The input parameter for this tool is the (.inf) files placed in various other folders/subfolders.(Say C:\Test\SampleInfFiles, C:\Test\SampleInfFiles\Inf2)
I want to create a batch file where i can run this tool recursively on the various folders.
I am not sure how to provide the folder name of the inf as the input parameter to the tool.
#echo off
for /r /d C:\Test\SampleInfFiles %%x in (dir /b *.inf) do(
pushd "%%x"
call C:\Test\ScanInf.exe
popd
)
I am new to all this. Could you please help create a batch file.
If I understand correctly, you need to specify the folder that contains one or more inf files to the executable, and not the inf files itself.
Apparently the order of parameters is important. for expects the part after /r to be a path. Furthermore, you can just specify * as a set.
The loop now browses all subfolders of the given folder. Inside the loop, it will check if that folder contains an inf file (on that level). If it does, the executable is called with the folder as parameter. Notice the use of ~ in the variable. This strips off any quotes, so you can safely add quotes without risking to have double quotes.
#echo off
for /d /r C:\Test\SampleInfFiles\ %%x in (*) do (
pushd "%%~x"
if exist %%x\*.inf call C:\Test\ScanInf.exe "%%~x"
popd
)
See: Using batch parameters
Here as a nice one-liner:
for /R "C:\Test\SampleInfFiles" /D %%X in (*.*) do if exist "%%~fX\*.inf" call C:\Test\ScanInf.exe "%%~fX"
If you want to run that in the command prompt directly, replace each %% by %.
I think the call command could be omitted.
I have a list of files to convert like this
C:\Users\jtl999\foo_001.jpg
C:\Users\jtl999\foo_002.jpg
To convert them manually I invoke the converter like this
convert_files.bat C:\Users\jtl999\foo_001.jpg
Basically what I want to do is read through the list of files one at a time and pass the file as a argument. On Linux I could use find and xargs but I am on Windows 7.
for %f in ("c:\users\jtl999\foo_*.jpg") do call convert_files.bat "%~ff"
For each file in the indicated set, call the batch file, passing as a parameter the full path to the file
The syntax is for usage from command line. To use this in a batch file: Change the parameters of for command so that the percent sign is doubled. %f should be %%f and %~f should be %%~f
for /f %i in ('dir /b /s "C:\Users\jtl999\foo_*.jpg"') do call convert_files.bat "%i"
use %%i instead of %i in batch-files.
You need the parameter /s to get the full path. Although this means, you will also get any files in sub directories that fits your filter (if there are some).