I need to do two things...
Rename all text files within a directory. Each file is named with a word and a number with a space between them. I want to remove the number from the file name.
For example....
House 21.txt -> House.txt
Each of the above files have the same content as their name. They each have one word and one number with a space between them. I need to be able to take the word and the number and save them as separate variables.
For example:
Car 2 -> Set var1=Car & var2=2
I just do not know the correct way to strip the appropriate info from the files when the content does not have the same amount of characters. If all I had to do was remove the last 5 characters I could do something like this:
#echo off
setlocal enabledelayedexpansion
for %%a in (*.TXT) do (
set oldName=%%a
set newName=!oldName:~0,-5!
echo !newName!>!newName!.txt
)
But each file is a different length and only removing 5 characters would not work for those that need 6 or more. Can anyone point me in the right direction?
A way to do that :
#echo off
setlocal enabledelayedexpansion
for %%a in (*.txt) do call:treat "%%~na"
exit/b
:treat
set count=1
for %%b in (%~1) do (
set $var!count!=%%b
set /a count+=1)
echo !$var1! - !$var2!
echo ren "%~1%.txt" !$var1!.txt
pause
This will create in every iteration $var1 and $var2 you can then rename %1 as !$var1!.
Just remove the echo if the output is correct for you.
You have 2 unrelated questions.
Part 1 - Rename the files
If all .txt files within the directory that match "* *.txt" are to be renamed, then you can do the following:
:: Preserve any existing files that have no extension
ren *. *.preserve
:: Strip off everything from the space onward
ren "* *.txt" "* "
:: Restore the .txt extension
ren *. *.txt
:: Restore the files with no extension
ren *.preserve *.
This solution has 4 steps, but it operates in bulk, so it can rename a great many files very quickly.
See How does the Windows RENAME command interpret wildcards? for help on why the above works
The above will also rename files like "word1 word2 45.txt", or "word1 word2.txt". You could use the following script to be more specific.
#echo off
for /f "delims=" %%F in (
'dir /b /a-d "* *.txt"^|findstr /ric:"^[^ ][^ ]* [0-9][0-9]*\.txt$"
) do for /f %%A in ("%%F") do ren "%%F" "%%A.txt"
This 2nd solution is very precice, but it must iterate each file, so it will be slower if there are a great number of files.
Part 2 - Capture the content of each line in two variables
#echo off
for /f "usebackq tokens=1,2" %%A in ("house 21.txt") do (
echo the word = %%A
echo the number = %%B
)
Once you have the line parsed into FOR variables %%A and %%B, you can do what you want with them. You could set an environment variable..., whatever.
Related
I'm trying to make a .bat file which iterates through every file in the directory which the .bat file is in, and renames all the files which follow the naming convention of MM_DD_YY*.* to YY_MM_DD*.*.
For example, 05.20.16 MyFile.txt would become 16.05.20 MyFile.txt.
I've managed to iterate through the filenames, but I'm having trouble with making a substring of the beginning 8 characters and comparing them to the format of ##.##.##.
#echo off
setlocal EnableDelayedExpression
for /f %%i in ('dir /b') do (
set fn=%%i
:: Need to compare first 8 chars to ##.##.##
if %fn:~0,8%==??.??.?? echo FollowsFormat
)
Any help is appreciated!
Provided:
the date in the file name is always followed by a space.
You can use delimiters . and spaceto seperate date elements and remaining file name into for variables %%A - %%D and rearrange them in the desired order.
To better distinguish old from new format I suggest to change the delimiter (at least temporarily) to a - and extend the year to 4 digits.
#echo off & setlocal EnableDelayedExpression
for /f "tokens=1-3* delims=. " %%A in (
'dir /b /A-D "??.??.?? *.txt" ^| findstr "^[01][0-9]\.[0-3][0-9]\.[0-9][0-9].*"'
) do Echo Ren "%%A.%%B.%%C %%D" "20%%C-%%A-%%B %%D"
For security reason the batch only echoes what it would rename
until you remove the echo in front of ren if the output looks OK.
I need a batch file that when run will look into a specific folder in Program Files (86) and copy and paste that file into another folder. Now I already know the code thanks to this website.
Here is my dilemma: the file changes from computer to computer. I know the first 4 letters are xxxx then followed by an unknown amount of numbers.
Can I make a .bat file that could look for the beginning of a file name?
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\abcd*" '
) DO (
SET "name=%%~na"
SET "name=9!name:~4!"
FOR /L %%z IN (0,1,9) DO SET "name=!name:%%z=!"
IF NOT DEFINED name ECHO(COPY "%sourcedir%\%%a" "%destdir%\"
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir 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. Append >nul to suppress report messages (eg. 1 file copied)
after setting delayedexpansion mode, perform a directory scan of the source directory, in /b basic mode /a-d without directories and assign each filename found to %%a.
set name fom the name part only of %%a, then remove the first 4 characters and include a 9 into the modified name.
Then remove all 0 to 9 from the result, and if name becomes empty, do the copy. Note that the 9 is added so that the string name remains non-empty until the very last iteration of the for /L loop.
#echo off
pushd "c:\program files (x86)"
FOR /f "delims=" %%a IN ('dir /b /a-d "xxxx*"^|findstr /i "\\xxxx[0-9][0-9]*\."') DO (
ECHO copy "%%a" "c:\another folder\"
)
popd
(NOTE: the copy command is disabled by an ECHO. Remove the ECHO, if the output looks correct.)
filter the output of the dir command to find:
- \\ a literal \ followed by
- xxxx the known prefix followed by
- [0-9] at least one number followed by
- [0-9]* zero or more numbers followed by
- \. a literal .
Pro's: no delayed expansion needed, should be (slightly) faster than Magoo's solution
To look also into subfolders, add /s to the dir command.
I am trying to come up with a batch file to copy files based on their names.
The filenames are in form aaa_xx-XX-ccc.txt where aaa and ccc do not matter (variable length), but xx are 2 character codes. I would like to copy the files into their respective xx folders and these folders would also be created by the script.
Here I found something that almost suit my needs:
Batch file to copy files based on characters in filename
#echo off
setlocal enableextensions enabledelayedexpansion
for %%x in (*.txt) do (
set "filename=%%x"
set "folder=!filename:~1,2!"
if not exist !folder! mkdir !folder!
copy "%%x" !folder!
)
But I would like to be looking for the xx not only by its position in the filename, but by the specific character (underscore) and position in the filename.
Is there any way to do it?
Update - example:
I have the following files in a single folder:
My-Project_ar-SA-2016114-12h33m10s.txt
My-Project_cs-CZ-2016114-12h33m8s.text
My-Project_da-DK-2016114-12h33m10s.txt
The "template" for the filenames is "[project-name]_[language-CODE]-[dateAndTime].txt
And I want to copy the first file into a different location\ar folder (for example "C:\Output\ar"), the second file into "C:\Output\cs" etc.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*_*-*-*.txt" '
) DO (
FOR /f "tokens=1*delims=_" %%c IN ("%%a") DO (
FOR /f "tokens=1,2*delims=-" %%q IN ("%%d") DO (
ECHO(COPY "%sourcedir%\%%a" "%destdir%\%%q\"
)
)
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir 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. Append >nul to suppress report messages (eg. 1 file copied)
It isn't clear whether you want the destination directory to be xx or XX. This is set up for xx for XX use %%r in place of %%q in the copy line.
Read the directory for files only using the mask _--.txt into %%a
Remove the leading characters up to the underscore by tokenising using _ and selecting %%d, the trailing portion
re-tokenise %%d on -. first token to %%q, second to %%r
Mix and match to create the copy command.
Note that your second filename, ...CZ... is a .text filename, not a .txt
According that all .txtfiles in the directory you're running the BAT are to be copied and the template is stricly what you described.
Here is an idea to do it :
#echo off
for /f "tokens=1,2,3* delims=_-" %%a in ('dir *.txt /b/a-d') do echo copy "%%a%%b%%c%%d" "c:\output\%%c"
Remove the echo before the copy if the Output is OK
Using a batch file I'm trying to generate a list of only folders within a location that contain a certain file type, let's call it *.abc
at the moment I only know how to echo a DIR command output to a file called folder.lst, I would like to expand on that and try to either
a) echo only folders containing the *.abc file type to folder.lst
b) remove references in folder.lst of folders that do not contain the *.abc file type.
I also tried having a FOR loop check each line to see if a *.abc file existed in that location and skip it, if not, but I just could not get that to work, here is an example of what I had.
setlocal enableextensions enabledelayedexpansion
FOR /F "delims=" %%C in (folder.lst) do (
set temp=%%C
if not exist !temp!\*.abc (goto skip) else (goto resume)
:resume
then my actions live here
:skip
)
but I am aware I am doing something wrong here...I just do not know what.
Maybe the /R form of the for command will help:
for /r "basedir" %%a in (.) do if exist "%%~a\*.abc" (
echo %%a contains .abc file(s)
)
The %%a will be the directories you want (with a trailing \., but you should be able to not care or accommodate this).
There are problems with such of the script as you have posted in that you can'y use labels within a block statement. You've also not provided any examples.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "lastdir="
FOR /r "%sourcedir%" %%a IN (*.abc) DO IF "!lastdir!" neq "%%~dpa" (
SET "lastdir=%%~dpa"
ECHO %%~dpa
echo "!lastdir:~0,-1!"
)
GOTO :EOF
Each directory found will be echoed twice - one with the trailing \ and once without.
You would need to change the setting of sourcedir to suit your circumstances.
#echo off
setlocal enableextensions disabledelayedexpansion
set "root=%cd%"
for %%a in ("%root%") do for /f "delims=: tokens=2" %%b in ('
dir /a-d /s "%root%\*.abc" ^| find "\"
') do echo(%%~da%%~pnxb
This executes a recursive dir command searching for the indicated file type under the starting point (change root variable to suit your needs). For each found folder we retrieve the folder from the dir header that precedes the file list (the lines that contain a backslash).
To separate the path from the rest of the information in the line, the colon is used as delimiter. As this will leave the drive out of the retrieved information, an aditional for is used to retrieve the drive from the folder reference.
From the command line:
for /f "delims=" %a in ('dir /s /b *.abc') do echo %~dpa >> folders.lst
In a batch file:
for /f "delims=" %%a in ('dir /s /b *.abc') do echo %%~dpa >> folders.lst
The above commands will place only the folder names containing the *.abc files in folders.lst.
Notes:
% should be replaced by %% when the command is used in a batch file.
The ~dp part of %~dpa expands %a to a drive letter and path only. Remove the d if you don't want the drive letter. The p path includes a trailing \ which may be interpreted as an escape character by some commands.
The above commands start the search in the current directory. To search from the root of the current drive you can do cd \ first.
For more information see FOR /F Loop command: against the results of another command and Parameters.
I have about 1000 images and they have name like "IMG-12223". I want to rename them to 1 2 3 4 ... 1000. How can I do that. I have written a batch script which list the files but I don't know how to rename each file. e.g. rename first image with name "IMG-12223" to 1 , second image with name "IMG-23441" to 2 and so on ...
for /r %%i in (*) do (
echo %c%
)
Here's the script. Just put the script in your folder and run it.
#echo off & setlocal EnableDelayedExpansion
set a=1
for /f "delims=" %%i in ('dir /b *') do (
if not "%%~nxi"=="%~nx0" (
ren "%%i" "!a!"
set /a a+=1
)
)
If you want to keep the extensions, i.e. rename "IMG-12223.jpg", "IMG-12224.jpg", etc to "1.jpg", "2.jpg", etc, you may use the following script.
#echo off & setlocal EnableDelayedExpansion
set a=1
for /f "delims=" %%i in ('dir /b *.jpg') do (
ren "%%i" "!a!.jpg"
set /a a+=1
)
[Update] Here're explanations for the lines mentioned in Jack's comment.
setlocal EnableDelayedExpansion
In general, we want the variable a to be delayed expansion when it's executed but not the line is read. Without it, the variable a cannot get its increased value but always 1.
For the detail of EnableDelayedExpansion, please refer to the answer https://stackoverflow.com/a/18464353/2749114.
for /f "delims=" %%i in ('dir /b *.jpg')
Here dir with /b option, lists only file names of all jpg files.
The for loop traverses and renames all jpg files.
For the delims option, since the default delimiter character is a space, without the option delims=, it fails with the image files with spaces in the file names. I.E. for an image file named "img with spaces.jpg", without the option, the value of %%i is "img" but not the whole name "img with spaces.jpg", which is incorrect.
For for loop, please refer to the page http://ss64.com/nt/for_f.html.
if not "%%~ni"=="%~n0"
I have change it to if not "%%~nxi"=="%~nx0" to be more accurate. And the codes attached have been updated.
It's actually used to avoid to rename the bat file itself. If we limit the renaming only upon "jpg" files, then the line is not needed.
%%~nxi is the file name with extension for each file traversed. And %~nx0 is the running bat file with extension. For details, please refer to the page DOS BAT file equivalent to Unix basename command?.
There is no need for a batch script. A simple one liner from the command line can do the job :-)
I use DIR /B to generate the list of files, piped to FINDSTR to number the files, all enclosed withn FOR /F to parse the result and perform the rename.
for /f "delims=: tokens=1*" %A in ('dir /b *.jpg^|findstr /n "^"') do #ren "%B" "%A%~xB"
Double the percents if you want to put the command in a batch script.
Try this, you have pair of namevalues in a text file then loop values and do the magic. Namevalues are separated by empty spaces. This allows you to map old->new filenames accordingly. Or you keep idx+1 counter and use it for new filenames.
keyvalue.bat
#echo off
set idx=0
for /F "tokens=1,2" %%A in (keyvalue.txt) do call :PROCESS "%%A" "%%B"
GOTO :END
:PROCESS
set var1=%~1
set var2=%~2
set /A idx=%idx%+1
echo %var1% goes to %var2% (%idx%)
GOTO :EOF
:END
pause
keyvalue.txt
file888.dat newfile1.dat
file333.dat newfile2.dat
file9.dat newfile3.dat
file01.dat newfile4.dat