Parse and Rename text files - windows

I need to rename all of these files to the 6 character Part Number(306391) on the 3rd line.
Currently i have:
setlocal enabledelayedexpansion
set first=1
for /f "skip=3 delims= " %%a in (Name.txt) do (
if !first! ==1 (
set first=0
echo %%a > out.txt
ren Name.txt %%a.txt
)
)
Which finds the 6 digit part number and renames the file to the correct name. But breaks if i use *.txt instead of the actual name of the .txt file. I need it to work for all .txt files in the directory.

Surround your for /f loop with another for loop, then reference the outer loop variable in your ren command. You can also eliminate the need for delayed expansion by using if defined for boolean checks. I put in other tweaks here and there. Just ask if you want details.
#echo off
setlocal
for %%I in (*.txt) do (
set first=
for /f "usebackq skip=3" %%a in ("%%~fI") do (
if not defined first (
set first=1
echo %%~nxI ^> %%a.txt
rem // uncomment this when you're satisfied that it works correctly
rem // ren "%%~fI" "%%a.txt"
)
)
)

This method should run faster, specially if the files are large, because just 4 lines of each file are read (instead of the whole file):
#echo off
setlocal EnableDelayedExpansion
rem Process all .txt files
for %%f in (*.txt) do (
rem Read the 4th line
(for /L %%i in (1,1,4) do set /P "line4=") < "%%f"
rem Rename the file
for /F %%a in ("!line4!") do ECHO ren "%%f" "%%a.txt"
)

Related

How to rename Windows files using extracted substring from current names

I have a directory of academic papers that were named using the convention below:
Author1-(Year)-Title.pdf
For example,
Jones-(2011)-XXX.pdf
Smith-(2002)-YYY.pdf
Johnson-(2015)-ZZZ.pdf
I would like to rename them as
(2011)-Jones-XXX.pdf
(2002)-Smith-YYY.pdf
(2015)-Johnson-ZZZ.pdf
That is, to extract the year from the file name and put it in front.
I tried the following code, which did not work
Setlocal enabledelayedexpansion
Set "Year=2013"
Set "Replace="""
For %%a in (*.pdf) Do (
Set "NewName=(%year%)-%%~a"
Ren "%%a" "%NewName%-File:%Year%=%Replace%!"
)
Pause&Exit
In case XXX also contains hyphens I'd suggest using tokens=1,2* to stop parsing the remainder of the file name.
I'd also remove the parentheses, when the year is first place there is no need to further emphasize it.
#Echo off
for /f "tokens=1-2* delims=-()" %%A in (
'Dir /b "*-(*)-*.pdf"'
) do Ren "%%A-(%%B)-%%C" "%%B-%%A-%%C"
Sample output
> dir /b
2002-Smith-YYY.pdf
2011-Jones-XXX.pdf
2015-Johnson-ZZZ.pdf
Not tested
for /f "tokens=1,2,3 delims=-" %%a in ('dir /b "*.pdf"') do (
echo ren "%%a-%%b-%%c" "%%b-%%a-%%c"
)
this will only echo the intended rename command.If it looks ok remove the echo word.
Derived form this SO article - it works:
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%x IN (*.pdf) DO (
FOR /f "tokens=1-3 delims=-" %%a IN ("%%~x") DO (
SET "Author=%%a"
SET "Year=%%b"
SET "Title=%%c"
ren %%x !Year!-!Author!-!Title!
)
)
Here is a reliable way of doing what you are asking for even if the author part contains - on its own. The title portion may even contain ( and ), but the author part must not. So this is the code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILES=.\*-(????)-*.pdf" & rem // (basic pattern to match correct files)
set "_REGEX=^[^()][^()]*-([0123456789][0123456789][0123456789][0123456789])-.*\.pdf$" ^
& rem // (precise filter to exclude files violating the demanded pattern)
if not defined _REGEX set "_REGEX=.*" & rem // (avoid trouble with empty filter)
rem // Loop through all matching files:
for /F "eol=: tokens=1,2,* delims=()" %%F in ('
dir /B /A:-D "%_FILES%" ^| findstr /I /R /C:"%_REGEX%"
') do (
rem // Store the extracted file name parts:
set "LEFT=%%F" & set "YEAR=%%G" & set "REST=%%H"
setlocal EnableDelayedExpansion
rem // Reassemble the name and rename the file:
ECHO ren "!LEFT!(!YEAR!)!REST!" "(!YEAR!)-!LEFT!!REST:*-=!"
endlocal
)
endlocal
exit /B
After having verified the correct output, remove the upper-case ECHO command to actually rename files.

Windows Batch job to precede all lines with filename

I have 50 text files and each text file has around 6000 lines. I am looking to make a batch job that will append the filename to each line of the text file.
I have a batch job to append data to the each line but cant wrap my head around getting the filename
This is what I have so far
#echo off
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N+=1
echo ^"(my filename)%%a^",>>output.txt
)
--- Example
filename 3315.txt
124123541234
1234123
2345623462356234
12341234562356245
Desired end result
3315124123541234
33151234123
33152345623462356234
331512341234562356245
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\R*.txt" '
) DO (
(
FOR /f "usebackqdelims=" %%q IN ("%sourcedir%\%%a") DO (
ECHO (%%a^)%%q
)
)>"%destdir%\%%~na.out"
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used a filemask of R*.txt to restrict the number of files processed on my test system.
Essentially, build a list of filenames using the dir command, and assign each to %%a in turn.
read each line of %%a into %%q and output to a new file in the destination directory made up of the name part of %%a (%%~na) and .out
--- later
To prepend the name part of the file to each line of the file, change
ECHO (%%a^)%%q
to
ECHO %%~na%%q
%%~na selects the Name part of %%a (see for /f|more from the prompt for more info)

How to generate automatic numbering of output files in a batch file?

I have a bunch of files say,
xxx111.txt
xxx112.txt
xxx113.txt
I want to remove the last 3 characters of all the file names and I'm using this script
#echo off
setlocal enabledelayedexpansion
set X=3
for %%f in (*) do if %%f neq %~nx0 (
set "filename=%%~nf"
set "filename=!filename:~,-%X%!"
ren "%%f" "!filename!%%~xf"
)
popd
pause
This runs perfectly when the output filenames are different. However, in the above case all file will be output as xxx.txt and the script throws me the error
"A duplicate file name exists, or the file cannot be found".
Is there any way to tweak this so that duplicate files will be renamed and maybe numbered 1,2,3...?
Unfortunately I cannot install any other software.
#echo off
setlocal EnableDelayedExpansion
set X=3
for /F "delims=" %%f in ('dir /A:-D /B') do if "%%f" neq "%~NX0" (
set "filename=%%~Nf"
set "filename=!filename:~,-%X%!"
if exist "!filename!%%~Xf" call :getNewName "%%~Xf"
ren "%%f" "!filename!%%~Xf"
)
popd
pause
goto :EOF
:getNewName ext
set i=0
:nextNum
set /A i+=1
if exist "%filename%%i%%~1" goto nextNum
set "filename=%filename%%i%"
exit /B
You should not use plain for %%f command when renaming files. Depending on where the new names are placed in the list of original names, they may be processed a second time by the for %%f. Always use for /F for renaming.

set values by file names in a directory

Hi I want to set value InFile for all text files in a directory which means that I want the batch file to load and do the command for all of the text files in the directory one by one.
Normally I just copy the command how many times files are then I replace Infile with every file name. By this code I get the file names and then I replace them.
cd /d "dir"
dir /a /b /-p /o:gen >names.txt
and here's the example of a command.
#Echo OFF
REM Set These Variables
SET "InFile=123.txt"
SET "OutFile=NowLoad.txt"
SET "Replace=KK"
SET "ReplaceWith=JJ"
REM Get Total Lines Number [including empty lines]
FOR /F %%A IN ('TYPE "%InFile%"^|find /v /c ""') DO SET "Till=%%A"
REM Create The OutFile with changes
SETLOCAL EnableDelayedExpansion
<"!InFile!" (
FOR /L %%a IN (1 1 0) DO SET /p "="
FOR /L %%A IN (1 1 %Till%) DO (
SET "line="
SET /P "line="
IF "!line!x" == "x" ( Echo.
) ELSE ( Echo !line:%Replace%=%ReplaceWith%!)
)
)>>"%OutFile%"
ENDLOCAL
no need to count the lines, just process every line:
setlocal enabledelayedexpansion
for %%f in (*.txt) do (
( for /f "delims=" %%A in (%%f) do (
set line=%%A
set line=!line:%Replace%=%ReplaceWith%!
echo(!line!
)
)>%%~nf.out
)
Note: the ( after echo handles empty lines (an empty line is written with no "echo is off" if !line! is empty)
edited to process all .txt files in the Folder. Because a fixed %oufile% would overwrite the same outfile with every processed infile, I changed it to a new Extension: <SameNameAsInputFile>.out
Another way...
Your script is DOIT.bat.
Change DOIT.bat to use a command line parameter for the filename you want to process.
#Echo OFF
REM Set These Variables
SET "InFile=%~1"
SET "OutFile=NowLoad.txt"
...
Create another file named CALLIT.bat
#ECHO OFF
FOR /F "usebackq tokens=*" %%f IN (`dir /b *.txt`) DO (
CALL DOIT.bat "%%~f"
)
Running CALLIT.bat will process every .txt file in the directory.

How to rename multiple files using a windows batch file script

I have and will have files which are named "x_1.txt x_2.txt x_3.txt, ..." my other program where I input these files cannot recognize the order so it sorts like this "x_1.txt , x_101.txt , x_2.txt"). a solution is to rename the files to x00001.txt , x00002.txt , ....
I have so far wrote the .bat file below, but two problems I have which , I'd be very glad if you help me solve them :
1- how can I remove the 'number'.txt from string x_'number'.txt
2- (solved) how can I use the variable of this string to rename the file name ( the rename part of this file is not working!)
cls
setlocal enabledelayedexpansion
set /A count=100000
for %%f in (*.txt) do (
set /a count+=1
set str=!count:~1!
echo !str!
echo %%f
set filename=%%f
set filename=!filename:~0,5! /Comment: here I want to just keep the x_ part which I don't know how"
echo !filename!
set str3=!filname!!str!
echo !str3!
/// ren %%f !str3!.txt /Comment: Here I cannot use the variable str3,
call:renamer %%f !str3!
)
:renamer
ren %1 %2.txt
Thanks in advance
If the following conditions are true:
You want to rename all of your .txt files in the current folder
All of the .txt files have exactly one _ in the name, immediately before the number
None of your file names contain !
Then the following will work
#echo off
setlocal enableDelayedExpansion
for %%F in (*.txt) do for /f "tokens=1,2 delims=_." %%A in ("%%F") do (
set num=0000%%B
ren "%%F" "%%A!num:~-5!.txt"
)
But to eliminate the conditions requires much more complicated code.
Here is one robust solution that should properly rename all files that meet the template.
It allows for multiple _ in the name.
It only renames files with a name that ends with _NNN.txt where NNN is a number
It properly handles ! in the file name.
Note that it will not properly handle numbers that exceeds 99999. It is simple to expand the degree of 0 padding.
#echo off
setlocal disableDelayedExpansion
pushd .
subst #: .
#:
for /f "eol=: delims=" %%F in ('dir /b /a-d *.txt^|findstr /er "_[0-9]*.txt"') do (
set "name=%%~nF"
setlocal enableDelayedExpansion
for /f "eol=: delims=" %%A in ("!name:_=\x!") do (
endlocal
set "file=%%F"
set "name=%%~pA"
set "num=%%~nA"
setlocal enableDelayedExpansion
set "num=0000!num:~1!"
set "name=!name:~1,-1!"
ren "!file!" "!name:\x=_!!num:~-5!.txt"
endlocal
)
)
popd
subst /d #:

Resources