I have a bunch of Pdf files with names like so:
Malcolm Gaskill - History.pdf
Manfred B. Steger - Globalization; A Very Short Introduction.pdf
I want to rename them to get rid of everything before the first hyphen so they end up like:
History.pdf
Globalization; A Very Short Introduction.pdf
How do I go about doing this?
Thanks
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*-*.pdf" '
) DO (
FOR /f "tokens=1*delims=-" %%b IN ("%%a") DO (
FOR /f "tokens=*" %%d IN ("%%c") DO (
ECHO(REN "%sourcedir%\%%~a" "%%~d"
)
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
Not particularly easy for a beginner, since the filenames may contain ; which is a separator like Space
First, perform a dir /b to get all of the required filenames which are applied to %%a using for /f with no delimiters.
Next, tokenise using - into %%b and %%c, then remove leading separators from %%c using tokens=* applying required filename to %%d.
Then mix-and-match to build the required rename command.
Related
I have went through a lot of guides for it, but havent found a way to do something similar to lets say turn all files in folder, like these files:
djhwu4s_cat_ruhg29.png
397y_dog_j0929_ej93.png
8yhh_owl.png
into these:
_cat.png
_dog.png
_owl.png
So basically removing everything from file names but a list of predefined strings i am searching for. In example above i would define list as "_cat", "_dog", "_owl". I know that each file will have only one of these variables, and there will be only one file with each of them in folder.
Will appreciate any tips on how to achieve that. Thanks in advance!
edit:
Here is what i came up with (with stuff i can understund) and what seems to be working fine now.
#echo off
setlocal enabledelayedexpansion
set v1=_cat-cat
set v2=_cat-owl
set v3=_cat
set v4=_dog
set v5=_owl
set v6=_horse
FOR /L %%a IN (1,1,6) DO (
rem echo %%a
rem echo !v%%a!
FOR /f %%f in ('dir /b /a:-D *!v%%a!.*') DO (
REN %%f !v%%a!.*
)
FOR /f %%f in ('dir /b /a:-D *!v%%a!_*.*') DO (
REN %%f !v%%a!.*
)
)
rem using two passes of this simpler code i can grasp and understund with dot and with underscore
rem after constructed variables value i make sure cat-cat is not recognised as and renamed to cat
rem no matter if im getting file with that variable as the last string before extension or another underscore
rem Gonna test it in combat now
For some reason this stuff doesnt work with files containing spaces and characters like:
"ab’c efg_dog.png"
FOR /L %%a IN (1,1,36) DO (
FOR /f %%f in ('dir /b /l /a:-D *!v%%a!.*') DO (
REN "%%f" "!v%%a!.*"
)
FOR /f %%f in ('dir /b /l /a:-D *!v%%a!_*.*') DO (
REN "%%f" "!v%%a!.*"
)
)
After further testing i have realised the problem starts with the %%f, and not the REN function as i thought. echo %%f before ren gives just the first part of the name to the first space, hence the REN function cant find the file. In case of "ab’c efg_dog.png" after finding the file with dir, the %%f becomes just "ab’c".
edit: After more tests and experiments and adding those "delims" to the code, the echo now shows proper, full names to be renamed, but it replaces that weird ’ character with ' for the REN command and thats why it still cant find the file to rename.
FOR /L %%a IN (1,1,36) DO (
FOR /f "delims=" %%f in ('dir /b /l /a:-D *!v%%a!.*') DO (
echo %%f
echo REN "%%f" "!v%%a!.*"
)
FOR /f "delims=" %%f in ('dir /b /l /a:-D *!v%%a!_*.*') DO (
echo %%f
echo REN "%%f" "!v%%a!.*"
)
)
#ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
PUSHD "%sourcedir%"
FOR /f "delims=" %%e IN ('dir /b /a-d "*_*" 2^nul ^|findstr /v /b "_"') DO (
FOR /f "tokens=2delims=_." %%y IN ("%%e") DO ECHO REN "%%e" "_%%y%%~xe"
)
POPD
GOTO :EOF
For lack of examples, here's a start.
Always verify against a test directory before applying to real data.
Process the list of filenames that match *_*; find those names that do not start _, pick the second string between the delimiters _ and . and rename using that string (in %%y), prefixed by _ and appended with the original extension.
The ren command is simply echoed to the screen for verification. When happy, remove the echo before the ren to actually execute the rename.
I am trying to replace URL encodings (e.g. %20 as a placeholder for a space) with their corresponding ASCII values in all filenames in a Windows folder and its subfolders.
If have a simple .bat file that can accomplish this, but it has limitations:
#echo off
Setlocal enabledelayedexpansion
Set "Pattern0=%%20"
Set "Replace0= "
Set "Pattern1=%%27"
Set "Replace1='"
Set "Pattern2=%%28"
Set "Replace2=("
Set "Pattern3=%%29"
Set "Replace3=)"
Set "Pattern4=%%5B"
Set "Replace4={"
Set "Pattern5=%%5D"
Set "Replace5=}"
For %%# in ("D:\Dropbox\Music\*.mp3") Do (
Set "File=%%~nx#"
Ren "%%#" "!File:%Pattern0%=%Replace0%!"
Ren "%%#" "!File:%Pattern1%=%Replace1%!"
Ren "%%#" "!File:%Pattern2%=%Replace2%!"
Ren "%%#" "!File:%Pattern3%=%Replace3%!"
Ren "%%#" "!File:%Pattern4%=%Replace4%!"
Ren "%%#" "!File:%Pattern5%=%Replace5%!"
)
Pause&Exit
There are two major limitations I'd like to fix:
It only checks the ..\Music\ folder root. I'd like it to look at
files in subdirectories, too.
It exits the For loop as soon as one of the renames are executed
(all %20's replaced first pass, for example, but nothing else).
And surely there is a better way to specify the encodings and their replacements (rather than variable pairs for each), but that's a nice-to-have feature.
These encodings always take the form %XX, where X are hexadecimal values.
To solve directory recursive search, you could use dir /s /b instead
FOR /F "delims=" %%# in ('dir /s /b "D:\Dropbox\Music\*.mp3"') Do (
...
)
Do not rename the file any time, only after all replacements
FOR /F "delims=" %%# in ('dir /s /b "D:\Dropbox\Music\*.mp3"') Do (
set "file=%%~#"
set "file="!File:%%20= !"
set "file="!File:%%28=(!"
...
move "%%~#" "!file!"
)
I'm using move here, because it works with full pathnames, too
To solve problems with exclamation marks in filenames/paths, you need to toggle delayed expansion
setlocal DisableDelayedExpansion
FOR /F "delims=" %%# in ('dir /s /b "D:\Dropbox\Music\*.mp3"') Do (
set "file=%%~#"
setlocal EnableDelayedExpansion
set "file="!File:%%20= !"
set "file="!File:%%28=(!"
...
move "%%~#" "!file!"
endlocal
)
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.
I'm trying to remove a certain part of a mp3's name.
So if mp3 is "X (2015)" I want it to recognize the "(2" and delete the rest of the name so I can delete it for every year.
Curiously enough, the most difficult part of this problem is to eliminate the space before the left parenthesis. The Batch file below just eliminate the last character of the new name; if the number of spaces before the left paren may be variable, then a different approach must be used.
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in ('dir /B *(2*.mp3') do (
for /F "delims=(" %%b in ("%%a") do set "name=%%b"
ECHO ren "%%a" "!name:~0,-1!.mp3"
)
Output example:
C:\> dir /B *.mp3
X (2015).mp3
Y (2012).mp3
C:\> test.bat
ren "X (2015).mp3" "X.mp3"
ren "Y (2012).mp3" "Y.mp3"
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*(*.mp3" '
) DO (FOR /f "tokens=1delims=(" %%g IN ("%%a") DO ECHO(REN "%sourcedir%\%%a" "%%~g%%~xa"
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
The directory list in /b basic form is processed and the filenames assigned to %%a. The filemask selects only those filenames that contain (
%%a is then partitioned into the part-before and the part after the first ( and the part before assigned to %%g
It's then a matter of stringing the command together.
I want to remove the part of a filename after the third "_" from thousand of files. The structure after the third "_" varies and contains "_" in some cases. The length of the first part varies so I can't just remove the first 15 characters. The result should be unique.
The filenames look like this:
00_TEXT_=Text00._AA1234L_AA1_1.pdf
00_TEX_=Text00._AA1234L_AA1_2.pdf
00_TEXT_=TextText00._DD2023A.pdf
00_TEXT_=Text00._AA2345L_BB1_1.pdf
00_TEXT_=Text00._AA2345L_BB1_2.pdf
The result should look like this:
AA1234L_AA1_1.pdf
AA1234L_AA1_2.pdf
DD2023A.pdf
AA2345L_BB1_1.pdf
AA2345L_BB1_2.pdf
Any idea why this is not working:
#echo off
setlocal enabledelayedexpansion
set deletestring=*_*_*_
for /f "delims==" %%F in ('dir /b ^| find "%deletestring%"') do (
set oldfilename=%%F
set newfilename=!oldfilename:%deletestring%=!
Ren "!oldfilename!" "!newfilename!"
)
I was able to get it working with this:
#echo off
setlocal enabledelayedexpansion
set deletestring=*_*_*_*
for /f "tokens=1,2,3,* delims=_" %%F in ('dir /b "%deletestring%"') do (
Ren "%%F_%%G_%%H_%%I" "%%I"
)
endlocal
Note that enabledelayedexpansion isn't really needed in the above.
Alternately, you could do this as a single line (no batch file needed):
for /f "tokens=1,2,3,* delims=_" %F in ('dir /b "*_*_*_*"') do Ren "%F_%G_%H_%I" "%I"
The idea is to simply split the matching filenames apart by underscores and then reconstruct the names during the rename process (%%F_%%G_%%H_%%I gives the original file name when going through the loop). Then rename the file to everything after the 3rd underscore, which is the %%I value.
Your FINDSTR search is wrong - a string of any characters (wildcard) is .*, not *.
Variable find/replace does not support wildcards, except for the !var:*search=! syntax that replaces everthing up until the first occurrence of "search".
There is no need for FINDSTR, all you need is DIR with normal wildcard masking.
You can use FOR /F to parse the name into tokens. I use two loops - the first to get the entire name, and the second to parse out the portion after the 3rd _.
The following should work:
#echo off
for /f "eol=: delims=" %%A in (
'dir /b /a-d *_*_*_*'
) do for /f "tokens=3* delims=_" %%B in ("%%A") do ren "%%A" "%%C"
Or you could use my jren.bat utility that renames files using regular expression replacement. It is a hybrid JScript/batch script that runs natively on any Windows machine from XP onward.
jren "^(.*?_){3}" ""
Use CALL JREN if you put the command within another batch script.