How to rename files based on CSV file with FOR /F loop? - windows

I'm trying to automate renaming of files based on a CSV such as the one shown below:
Name,FullName
John,JohnDoe
Jane,JaneDoe
Joe,JoeDoe
Let's say I have 3 text files within the same folder of my .bat called John.txt, Jane.txt, Joe.txt and I want to rename John.txt to JohnDoe.txt, etc.
I am getting "The system cannot find the file specified" no matter how much I alter the filepath in my rename. Here is a basic rundown of what I have. What am I doing wrong here or what other way should I approach this? I appreciate all feedback.
#echo off
setlocal enabledelayedexpansion
set csvpath=C:\Users\user1\OneDrive\Documents\BatchExamples\stuff.csv
FOR /F "usebackq skip=1 tokens=1,2 delims=," %%g IN (!csvpath!) do (
set person=%%g
set name=%%h
echo My name is !person! and my full name is !name!
rename !person!.txt !name!.txt
)
pause

This is how I would do it:
#echo off
set "csvpath=C:\Users\user1\OneDrive\Documents\BatchExamples\stuff.csv"
FOR /F "usebackq skip=1 tokens=1,2 delims=," %%g IN (`findstr /v /c:":-:-:" "%csvpath%"`) do (
echo My name is "%%g" and my full name is "%%h"
rename "%~dp0\%%g.txt" "%%h.txt"
)
pause
This code is a bit cleaner and more robust, in that file paths and names can have special characters (like &) without breaking the script.
findstr /v /c:"SEARCHSTRING" "FILEPATH" tells findstr to print every line within FILEPATH excluding (/v) lines with SEARCHSTRING. This doesn't really change much from what you had previously, however it is a bit more robust.
In the rename command, I set it to %~dp0 and then the file name, %~dp0 is the path to where your .bat script is.

Related

BATCH: Delete parts of filename using substring not working

I have several .csv files in one folder. They are saved automatically but with spaces and execution date and time (in seconds) with amount of containing lines.
So far I was not able to run my powershell script with files containing spaces. So I tried to rename filenames using batch. so far nothing is working fine. Either in cmd-line or with a batch file.
Trying to loop in folder to find .csv is working but defining a string and then substring parts of the file not.
for %%i in ('dir *.csv /b /s') do set string = %%~ni
set substr=!string:~20,25!
echo !substr!
I tried first to use % instead of ! but didn't worked as well. Tried to use pipes for the loop as well, didn't worked.
So far my output is just
!string:~20,25!
My output has to be just the "real" filename of the report without anything else before or after it.
For example, do with that path and filename
C:\Users\Username\CSV_Files\Reportoutput Report_2017 2018-01-09T07_10_33.1924R.csv
this
C:\Users\Username\CSV_Files\Report_2017.csv
When I'm able to extract just the filename without any spaces or leading chars like "Reportoutput" (which is always the same) or starting time of report or containing lines in the report I could use that string and combine it with the path where files are saved.
Any ideas? Why is my "substring" not working at all? Do I miss some action? Some code?
I'm using windows.
Based on the file name structure you've presented and looping in one folder, (the current directory), as stated and used in your example code:
#Echo Off
For %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
If you wanted to check inside subfolders of the currect directory then change it to this:
#Echo Off
For /R %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
…and if you want to specify the base directory name then you can do so like the following two examples which use %UserProfile% for demonstration purposes, (change as appropriate).
#Echo Off
For /R "%UserProfile%" %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
and:
#Echo Off
CD /D "%UserProfile%" 2>Nul||Exit /B
For /R %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
Instead of splitting the names using character numbers, this simply takes the second token of the file name string delimited by spaces and adds the original file extension to it in a rename command.

Trim Date from file name windows script

How do you trim the date from a text file. For example, I have multiple files like:
test_MX_abc_20091011.txt
test_MX_pqrdhdsu_20091011.txt
test_MX_xyieuz_20091011.txt
All files will have test_MX in common but the 3rd part will of different size.
I would like to change into:
test_MX_abc.txt
test_MX_pqrdhdsu.txt
test_MX_xyieuz.txt
I know how to change the file if name is like test_20091011.txt with the below code, But if name has more string along with date, how to do that?
for /F "tokens=1 delims=_" %%i in ("%%~na") do (
move /Y %%~fa %data_in%\%%i%%~xa >nul
)
Thanks in advance.
This rename operation can be done for example with:
#echo off
for /F "tokens=1-3* delims=_" %%A in ('dir /A-D /B test_MX_*.txt') do (
ren "%%A_%%B_%%C_%%D" "%%A_%%B_%%C.txt"
)
Each file name is separated into 4 strings assigned to loop variables A to D with using underscore as separator. The loop variable D takes everything of file name after third underscore.
Or also working for the 3 files:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%F in ('dir /A-D /B test_MX_*.txt') do (
set "ActFileName=%%~nF"
set "NewFileName=!ActFileName:~0,-9!"
ren "%%~F" "!NewFileName!.txt"
)
endlocal
This solution assigns the name of a file without file extension and path to environment variable ActFileName. Next a new environment variable with name NewFileName is defined with name of active file without the last 9 characters (underscore and date string). This modified file name is used next in the rename operation.
Other solutions using commands for, set and ren can be found on Stack Overflow.
Search with the string
[batch-file] for set rename files
and more than 600 results are presented all using more or less something like above.
For details on the used commands, open a command prompt window, execute one after the other following commands and read output help.
dir /?
for /?
ren /?
set /?

Gathering list of file extensions - "The command line is too long" workaround

I am currently using this batch file to scan through a Windows file system and save a .txt document of all the file extensions in that system:
Cmd Line Command:
NameOfBatchFile.bat >List.txt
BatchFile Code:
#echo off
set target=%1
if "%target%"=="" set target=%cd%
setlocal EnableDelayedExpansion
set LF=^
rem Previous two lines deliberately left blank for LF to work.
for /f "tokens=*" %%i in ('dir /b /s /a:-d "\\PathOfMyWindowsDirectory"') do (
set ext=%%~xi
if "!ext!"=="" set ext=FileWithNoExtension
echo !extlist! | find "!ext!" > nul
if not !ERRORLEVEL! == 0 set extlist=!extlist!!ext!:
)
echo %extlist::=!LF!%
endlocal
The code works great on small folders but if I provide it a folder with too many subfolders, the command line will process then provide the following error:
The command line is too long.
The command line is too long.
The command line is too long.
The command line is too long.
The command line is too long.
The command line is too long.
The command line is too long.
The input line is too long.
I can't edit the filesystem to decrease subfolders, does anyone know another way to get this to work?
The problem in your code is the concatenation of elements inside a variable, that can generate a long list of extensions that will end generating a excesively long command line.
#echo off
setlocal enableextensions disabledelayedexpansion
set "target=%~1"
if "%target%"=="" set "target=%cd%"
for /r "%target%" %%a in (*) do if not defined "\%%~xa\" (
if "%%~xa"=="" (echo(FileWithNoExtension) else (echo(%%~xa)
set ""\%%~xa\"=1"
)
endlocal
This uses the environment to store the information of seen extensions by setting a variable for each one. If the variable is not set, this is the first time the extension is found and is echoed to console.
I think this is the fastest way to get the result to this problem.
#echo off
setlocal
set target=%1
if "%target%"=="" set target=%cd%
for /R "%target%" %%a in (*.*) do set ext[%%~Xa]=1
for /F "tokens=2 delims=[]" %%a in ('set ext[') do (
if "%%a" equ "=1" (
echo FileWithNoExtension
) else (
echo %%a
)
)
Previous method may be easily modified in order to get the number of files that have each extension; just modify the set ext[%%~Xa]=1 by set /A ext[%%~Xa]+=1 and modify the tokens in the for /F accordingly.
This gives you a sorted list of all the extensions very quickly.
#echo off
set "target=%~1"
if "%target%"=="" set target=%cd%
dir "%target%" /b /s /a-d |repl ".*(\..*)" "$1" |repl ".*\\.*" "FileWithNoExtension"|sort|uniq >file.txt
This uses a helper batch file called repl.bat (by dbenham) - download from: https://www.dropbox.com/s/qidqwztmetbvklt/repl.bat
This uses a helper batch file called uniq.bat (by aacini) - download from: https://www.dropbox.com/s/71o38a4ljnqgqjh/uniq.bat
Place repl.bat and uniq.bat in the same folder as the batch file or in a folder that is on the path.

How to batch rename files in a directory from a list of names in a text file

I'd like to use Power Shell or a batch file to rename several files in a folder based on a list in a text file. Essentially I want to append the file names with the author's last names (which I have stored in a separate text file).
E.g. Currently I have:
C:\myfiles
9-ART-2013.pdf
4-EGO-2013.pdf
2-ART-2013.pdf
My text file (in same order as files):
C:\myfiles
_Smith
_Jenkins
_McMaster
I want the files to be renamed as follows:
9-ART-2013_Smith.pdf
4-EGO-2013_Jenkins.pdf
2-ART-2013_McMaster.pdf
I've seen similar problems where people want to recursively rename files but they are always using a generic common appending element like adding an underscore or pre-pending with folder name, etc.
e.g. https://serverfault.com/questions/6268/easy-way-to-rename-all-files-in-a-directory-in-windows
In PowerShell it would be:
$names = Get-Content c\myfiles
Get-ChildItem C:\somedir\*.pdf | Sort -desc |
Foreach {$i=0} {Rename-Item $_ ($_.basename + $names[$i++] + $_.extension) -WhatIf}
If it looks like it will copy correctly, remove the -WhatIf.
Any of the above are likely workable solutions with just a little tweaking but the simplest thing to do was to simply create one text file with each row containing "the current filename"... a TAB... then "the filename I wanted".
9-ART-2013.pdf 9-ART-2013_Smith.pdf
4-EGO-2013.pdf 4-EGO-2013_Jenkins.pdf
2-ART-2013.pdf 2-ART-2013_McMaster.pdf
Then save the file as rename_list.txt and create a batch file with the following code.
for /F "tokens=1,2" %%a in (rename_list.txt) do ren "%%a" "%%b"
pause
You can delete the pause line once you get it tweaked and running correctly. Just copy the rename_list.txt and batch files to the folder with the files you want to rename and run the batch file. If you have a large folder with many files names you can get them in a text file by running a batch file with the following line.
dir /D > filename_scrapper_output.txt
It will create a text file filename_scrapper_output.txt that you can use to start your rename_list.txt file for above.
Another way to achieve the same thing:
#echo off
setlocal EnableDelayedExpansion
rem Load the list of authors:
set i=0
for /F %%a in (myfiles.txt) do (
set /A i+=1
set "author[!i!]=%%a"
)
rem Do the rename:
set i=0
for /F %%a in ('dir /b *.pdf') do (
set /A i+=1
for %%i in (!i!) do ren "%%a" "%%~Na!author[%%i]!%%~Xa"
)
EDIT: New method added
If the list of names file have the "OLD-Name NEW-Name" structure, then the code is much simpler:
for /F "tokens=1,2" %%a in (myfiles.txt) do ren "%%a" "%%b"
Note that the names must be separated by a space.
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
<Text.txt (
for /f "tokens=1*delims=_" %%a in ('dir /b /a-d /o-d *-*-*.pdf') do if "%%b"=="" (
set "xand="
set /p "xand="
echo ren "%%~a" "%%~na!xand!%%~xa"
))
Taking Endoro's and simplifying:
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
<texts.txt (
for /f "tokens=* delims=* " %%a in ('dir /b /a-d /o-d *-*-*.pdf') do (
set "xand="
set /p "xand="
ren "%%~a" "%%~na!xand!%%~xa"
))

Renaming files with a windows batch file

I have a series of files that I need to rename on a daily basis. The files I receive have the following format: yyyyMMdd_hhmmss_xxx.someFileName.txt I need to strip out the time stamp in the middle as well as the three digit field preceeding the filename and leave the date and the "someFileName.txt" piece. The resulting filename should look like: yyyyMMddsomeFileName.txt
I'm pretty clueless when it comes to bat files, I've done some experimenting:
#setlocal EnableDelayedExpansion
#for %%i in (.\*.txt) do call rename %%i
:rename
#set dateString=%%i:~0,8%
#set nameString=%%i:~20%
#set combinedString=%dateString%%nameString%
#echo %combinedString%
Clearly, this doesn't actually rename anything yet. It's just supposed to print the combinedString output. I'm getting a syntax error: "The syntax of the command is incorrect ~0,8 ~20"
What's going on here? What's the correct approach for this?
This should work for what you wanted.
#echo off
for /f "delims=" %%X in ('dir /a:-d /b *.txt') do (
for /f "tokens=1,2,3,* delims=_." %%A in ("%%~nxX") do (
echo %%A%%D
)
)
Replace the echo command with ren "%%~fX" "%%A%%D" when you want to rename them.

Resources