1

I have two files :

old_names.txt
  oldname1
  oldname2 

new_names.txt 
  newname1
  newname2 

I would like to search my folder for file names containing "old_names" and replace "old_name" string with corresponding "new_name".

for /f %%i in (old_names.txt) do (

 // get corresponding %%j new_name

 for /f %%a in ('dir /b /a-d *%%i*') do ren %%a %%j

)

How can I retrieve the corresponding new_name ?

Malcom
  • 468
  • 8
  • 21
  • Do you have to have the file names in 2 different files? Why not put them in 1 file? Seems like you want to do `ren file1 file2` in batch, if you already know what the file names are, simply create one file seperated by a space. i.e `file1.txt file2.txt` and do `for /f "tokens=1,2" %%i in (names.txt) do ren "%%i" "%%j"` – Gerhard Sep 10 '18 at 14:36
  • I tried with `for /f "tokens=1,2" %%i in (test.txt) do ren "%%i" "%%j"` and nothing is happening, am I missing a line ? – Malcom Sep 10 '18 at 14:41
  • and you have both file names inside of `test.txt`? are the files you want to rename in the same directory as the script? – Gerhard Sep 10 '18 at 14:42
  • Yes, I do, test.txt is as such : *dummy replacement* and I have a file named *tmp_dummy.jpg*. It says file not found. – Malcom Sep 10 '18 at 14:44
  • no, that won't work like that. if you want to do part replacements, then you asked the question incorrectly. Let me add that. – Gerhard Sep 10 '18 at 14:48
  • Sorry if I wasn't clear, i wanted file names containing the string yes, not exactly. – Malcom Sep 10 '18 at 14:51
  • edited my asswer. Please test. – Gerhard Sep 10 '18 at 15:03

2 Answers2

2

For your file pair concept you basically need to read the two files line by line simultaneously, if I understand correctly, which can be accomplished like illustrated in this answer. So here is a possible code:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_ROOT=D:\path\to\root_dir" & rem // (directory containing files to rename)
set "_FILE1=D:\path\to\old_names.txt"
set "_FILE2=D:\path\to\new_names.txt"

rem // Count number of lines of 1st file (2nd file is not checked):
for /F %%C in ('^< "%_FILE1%" find /C /V ""') do set "NUM1=%%C"

setlocal EnableDelayedExpansion
rem // Change into root directory:
cd /D "%_ROOT%" || exit /B 1
rem // Here input redirection is used to read both files simultaneously:
9< "!_FILE1!" 8< "!_FILE2!" (
     rem // Loop through the number of lines of the 1st file:
     for /L %%I in (1,1,%NUM1%) do (
         rem // Read a line from the 1st file:
         <&9 (set "LINE1=" & set /P "LINE1=")
         rem // Read a line from the 2nd file:
         <&8 (set "LINE2=" & set /P "LINE2=")
         rem /* Assign line strings to `for` variables to later avoid nested
         rem    delayedly expanded environment variables: */
         for /F "tokens=1,2 delims=| eol=|" %%I in ("!LINE1!|!LINE2!") do (
             rem // Get list of files matching the partial name:
             for /F "delims= eol=|" %%F in ('dir /B /A:-D "*!LINE1!*"') do (
                 endlocal
                 rem // Store current file name:
                 set "NAME=%%F"
                 setlocal EnableDelayedExpansion
                 rem // Do the actual sub-string replacement and rename file:
                 ECHO ren "!NAME!" "!NAME:%%I=%%J!"
             )
         )
     )
)
endlocal

endlocal
exit /B

After having checked the correct output, remove the upper-case ECHO command!

This does not work if any of the following characters occur in the two name files: =, !, ^; the ~ must not occur as the first character in any line of the first file (old names).

aschipfl
  • 33,626
  • 12
  • 54
  • 99
1

As per my comment. Create a single file called names.txt and add the strings you want to replace and what you want to replace it with:

dummy replacement
dummy2 replacement2

then the script needs to be in the same directory, or you have to specify path to the files:

@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2" %%i in (names.txt) do (
  for /f %%a in ('dir /b /a-d ^| findstr "%%i"') do (
    set "oldname=%%a"
    set "newname=!oldname:%%i=%%j!"
    echo ren "!oldname!" "!newname!"
  )
)

or by specifying path:

@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2" %%i in (names.txt) do (
  for /f %%a in ('dir /b /a-d "D:\PATH" ^| findstr "%%i"') do (
    set "oldname=%%a"
    set "newname=!oldname:%%i=%%j!"
    echo ren "!oldname!" "!newname!"
  )
)

Once you are happy that it prints the files to replace to screen, simply remove the echo from the last line of code to actually perform the ren

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Gerhard
  • 22,678
  • 7
  • 27
  • 43