You are not logged in.
Pages: 1
Hi, I have .csv file with 3 columns, delimiter is "|", .
I need to use it to rename files, last(3rd) column is current filename. First two field joined should be new file name.
As in example, some fields contain space, don't know is that could be a problem or not.
Files are in folder C:\all\ as well in sub folders in C:\all\.
example
New|Name 1|cName1
--
Wanted: cName1> New Name 1
@echo off
for /f "tokens=1,2,3 delims=|" %%A in (C:\all\c.csv) do (
for /R "C:\all\" %%C in ("%%~C") do (
ren "%%~C" "%%A %%B"
)
)
:END
when I test, it started renaming sub folders, not files. I don't want to rename sub folders only files.
Offline
for /R has some weird (buggy) behaviours. I think this will work:
@echo off
for /f "tokens=1,2,3 delims=|" %%A in (C:\all\c.csv) do (
for /f "usebackq tokens=*" %%D in (`dir /b/s "C:\all\%%~C"`) do (
ren "%%~D" "%%A %%B"
)
)
This is a direct equivalent (for good or ill) of what you were trying to do with "for /r". It might be quite slow if there are lot of sub directories. There are other ways to skin this cat, which may perform better -- depending on your use case.
Last edited by bluesxman (22 Jul 2019 17:20)
cmd | *sh | ruby | chef
Offline
Thanks for answer. I tried it. Yes it can be slow with a lot of files. It looks like it is listing against all files one by one, there are 20K files in my folder. Any way to make it faster?
Offline
With a quick hack, this might be a bit faster (untested):
@echo off
set ALLFILE="%TEMP%\%~n0.tmp"
dir /b/s "C:\all" > "%ALLFILE%"
for /f "tokens=1,2,3 delims=|" %%A in (C:\all\c.csv) do (
for /f "usebackq tokens=*" %%D in (`findstr /e /l "\%%~C" "%ALLFILE%"`) do (
ren "%%~D" "%%A %%B"
)
)
The problem here is you have two lists of stuff, and you don't seem to have any prior knowledge of whereabouts in C:\all you can expect to find the items in your CSV file.
EDIT:
Some potential for incremental improvement here (though having to invoke a binary for each item in the CSV suuuuuuucks):
@echo off
set "ALLFILE=%TEMP%\%~n0.all.tmp"
set "MATCH=%TEMP%\%~n0.match.tmp"
set "FILTERED=%TEMP%\%~n0.filtered.tmp"
dir /b/s "C:\all" > "%ALLFILE%"
type nul > "%MATCH%"
for /f "tokens=3 delims=|" %%A in (C:\all\c.csv) do (
(set /p "out=\%%~A" <nul && echo:) >> "%MATCH%"
)
findstr /l /e /g:"%MATCH%" "%ALLFILE%" > "%FILTERED%"
for /f "tokens=1,2,3 delims=|" %%A in (C:\all\c.csv) do (
for /f "usebackq tokens=*" %%D in (`findstr /l /e "\%%~C" "%FILTERED%" 2^>nul`) do (
ren "%%~D" "%%A %%B"
)
)
Last edited by bluesxman (22 Jul 2019 17:39)
cmd | *sh | ruby | chef
Offline
I got:
.tmp""` was unexpected at this time.
Offline
Hmm can't see where that is coming from.
Can you remove the @echo off and copy/paste the output?
cmd | *sh | ruby | chef
Offline
Turns out it takes a lot of time because I have tens of thousands of files. So I turn to a method to rename without loop. Thanks for your help.
Offline
Pages: 1