Rename text file based on content

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
jeff p
Posts: 42
Joined: 28 Jul 2009 10:21

Rename text file based on content

#1 Post by jeff p » 29 May 2013 11:26

I have a few hundred text files (of various names) in a folder. C:\Renamed_Files\

I'm in desperate need of a batch file which will rename each text file based on the 3rd line of their respected text..and if possible, not to exceed 40 characters from the left. (each file varies in length, some have more or less than 40 char.)

ie: in TextFile01.txt

line 1
line 2
line 3 < rename this file based on this line
line 4

Many thanks for any help.

Jeff

Endoro
Posts: 244
Joined: 27 Mar 2013 01:29
Location: Bozen

Re: Rename text file based on content

#2 Post by Endoro » 29 May 2013 12:39

try this. Look at the output and remove the word "echo" before "rename" if it is OK:

Code: Select all

@echo off&setlocal
cd Renamed_Files
for /f "delims=" %%i in ('dir /a-d/b *.txt') do (
   set "nname="
   set "fname=%%~i"
   for /f "usebackqskip=2delims=" %%f in ("%%~i") do if not defined nname set "nname=%%f"
   setlocal enabledelayedexpansion
   set "nname=!nname:~0,40!"
   echo rename "!fname!" "!nname!"
   endlocal
)

jeff p
Posts: 42
Joined: 28 Jul 2009 10:21

Re: Rename text file based on content

#3 Post by jeff p » 29 May 2013 19:30

Thanks, once again Endoro. The renaming functionality works great!!
I needed to remove the "Echo" for it to work.

...however how can I add the ".txt" extension for the final output text file, in your code?
It renames the file without an extension.


Thanks again!

Jeff

Endoro
Posts: 244
Joined: 27 Mar 2013 01:29
Location: Bozen

Re: Rename text file based on content

#4 Post by Endoro » 29 May 2013 20:56

simply add the extension to the new name:

Code: Select all

@echo off&setlocal
cd Renamed_Files
for /f "delims=" %%i in ('dir /a-d/b *.txt') do (
   set "nname="
   set "fname=%%~i"
   for /f "usebackqskip=2delims=" %%f in ("%%~i") do if not defined nname set "nname=%%f"
   setlocal enabledelayedexpansion
   set "nname=!nname:~0,40!"
   echo rename "!fname!" "!nname!.txt"
   endlocal
)

Aacini
Expert
Posts: 1680
Joined: 06 Dec 2011 22:15
Location: México City, México

Re: Rename text file based on content

#5 Post by Aacini » 29 May 2013 22:49

If your text files are large, the Batch solution below will run faster.

Code: Select all

@echo off
setlocal
cd C:\Renamed_Files
for /F "delims=" %%a in ('dir /A-D /B *.txt') do (
   for /F "tokens=1* delims=:" %%b in (
          'findstr /N "^" "%%a" 2^>NUL ^| findstr "^3:" 2^>NUL ^| (set /P @^=^& set @ ^)'
                                      ) do set "line3=%%c"
   setlocal EnableDelayedExpansion
   ECHO ren "%%a" "!line3:~0,40!%%~Xa"
   endlocal
)

Antonio

jeff p
Posts: 42
Joined: 28 Jul 2009 10:21

Re: Rename text file based on content

#6 Post by jeff p » 29 May 2013 22:55

I thank you Endoro!

this script is a life saver!!

Thanks Aacini for the code!.. Fortunately my text files are quite small, but there are many of them

Thanks again for the help guys!

Jeff

Endoro, If I may ask, what area of the code designates the line count?
If in the future I needed to extract the 1st line, or perhaps the 4th line what part could I modify?

Endoro
Posts: 244
Joined: 27 Mar 2013 01:29
Location: Bozen

Re: Rename text file based on content

#7 Post by Endoro » 29 May 2013 23:43

select the desired line with the "skip" parameter:

Code: Select all

   for /f "usebackq skip=2 delims=" 


for the
  • first line remove the skip parameter ("skip=0" doesn't work)
  • 2nd line: skip=1
  • 3rd line: skip=2
  • and so on
My code doesnt count empty lines, if you need this you should choose Aacini's (except you have file names with carets "^" or exclams "!" , what is not recommended).

jeff p
Posts: 42
Joined: 28 Jul 2009 10:21

Re: Rename text file based on content

#8 Post by jeff p » 30 May 2013 12:05

Thanks Endoro!

Cheers!

Aacini
Expert
Posts: 1680
Joined: 06 Dec 2011 22:15
Location: México City, México

Re: Rename text file based on content

#9 Post by Aacini » 30 May 2013 20:33

jeff p wrote:I have a few hundred text files (of various names) in a folder.
. . .
Fortunately my text files are quite small, but there are many of them

Jeff


I further analysed this problem looking for a way to rename all files in less time and devised a multi-thread solution that would make good use of the unused time gaps that may occur in differently timed devices. The idea is run the process at the maximum speed that allows the slowest device (ie: hard disk) when it is continuously used (with no pauses). Of course, the result of this method will entirely depend on the computer hardware.

The Batch file below take in the first parameter the number of asynchronous threads that will be created. This way, the total number of files to be renamed will be divided by this number and each resulting block of files will be processed by a different simultaneous thread.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem Multi-thread file rename program
if "%1" equ "Thread" goto ProcessBlock

rem Create the list of file names and count they
cd C:\Renamed_Files
set numFiles=0
(for %%f in (*.txt) do (
   echo %%f
   set /A numFiles+=1
)) > fileNames.tmp

rem Get number of threads and size of each block
set numThreads=%1
if not defined numThreads (
   set /A numThreads=1, blockSize=numFiles
) else (
   set /A blockSize=numFiles/numThreads
)

rem Create asynchronous threads to process block number 2 up to numThreads
if exist thread.* del thread.*
for /L %%t in (2,1,%numThreads%) do (
   echo %time% > thread.%%t
   start "" /B "%~F0" Thread %%t
)

rem Process block number 1
set count=0
for /F "delims=" %%f in (fileNames.tmp) do (
   set line3=
   for /F "usebackq skip=2 delims=" %%a in ("%%f") do if not defined line3 set "line3=%%a"
   ren "%%f" "!line3:~0,40!.txt"
   set /A count+=1
   if !count! equ %blockSize% goto endFirstBlock
)

:endFirstBlock

rem Wait for all asynchronous threads to end
if exist thread.* goto endFirstBlock

rem Delete the auxiliary file and end
del fileNames.tmp
goto :EOF


rem Process blocks 2 and up (asynchronous thread)

:ProcessBlock
set /A skip=(%2-1)*blockSize, count=0
for /F "skip=%skip% delims=" %%f in (fileNames.tmp) do (
   set line3=
   for /F "usebackq skip=2 delims=" %%a in ("%%f") do if not defined line3 set "line3=%%a"
   ren "%%f" "!line3:~0,40!.txt"
   set /A count+=1
   if !count! equ %blockSize% goto endBlock
)
:endBlock
del thread.%2
exit

The above Batch file assume that file names have not exclamation marks. If this point is required, the appropriate setlocal/endlocal commands may be included, but this detail will slow down the process.

You may do several timing tests with the same set of files varying the parameter value starting at 2 and growing up until a value gives a timing greater than the previous one. If you complete these timing tests, post the results please! I would like to review they. :)

Antonio

Serpent
Posts: 12
Joined: 08 Sep 2013 17:18

Re: Rename text file based on content

#10 Post by Serpent » 08 Sep 2013 17:26

hay after a long time searching i found the batch that i need , and it works
but i have a quastion the bath is for line 3 , but i am need it for line 1
i believe it is easy to change that but no i am strugeling with it
my file start with: // some file , my txt file must renamed in some file.txt
probely its a small change in the batch but i dont see it
can you please help me out

W.r.
Rob

ShadowThief
Expert
Posts: 997
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Rename text file based on content

#11 Post by ShadowThief » 08 Sep 2013 17:32

First line stuff is easy; you can just say

Code: Select all

set /p variable=<filename.txt


which will store the first line in the text file to %variable%

Serpent
Posts: 12
Joined: 08 Sep 2013 17:18

Re: Rename text file based on content

#12 Post by Serpent » 08 Sep 2013 17:39

if you know where to look , but i am a noob i can read it i understand it a bit , but put a line in ...........
so if i look at the batch from Aacini where do i put youre line or change a line to make it work
:roll:

tnx

ShadowThief
Expert
Posts: 997
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Rename text file based on content

#13 Post by ShadowThief » 08 Sep 2013 18:23

You should be able to take Aacini's code and replace both instances of

Code: Select all

set line3=
   for /F "usebackq skip=2 delims=" %%a in ("%%f") do if not defined line3 set "line3=%%a"


with

Code: Select all

set /p line1=<%%f


but I haven't tested it, and honestly I'm just now discovering that batch can do multithreading and it's kind of blowing my mind trying to figure out how it's working.

Serpent
Posts: 12
Joined: 08 Sep 2013 17:18

Re: Rename text file based on content

#14 Post by Serpent » 09 Sep 2013 01:49

haha do you understand me now , and i am a bit of a noob....
but tnx for trying but it didn't work , when i do that i get a extra txt file named 0,40.txt

foxidrive
Expert
Posts: 6033
Joined: 10 Feb 2012 02:20

Re: Rename text file based on content

#15 Post by foxidrive » 09 Sep 2013 02:55

Serpent, tell us what you need to do.

Post Reply