0

I am trying to make a batch script to rename files in a directory. All the filenames are stored in a text file and I am reading them in a script. File names are the updates released by microsoft. Since the filenames downloaded are not in a patterned format, I am having difficulty to rename hundreds of files. for eample if a file name is - windows6.1-KB1234567 update for_IE10 for RCE.msu
I want to rename it to KB1234567
I got success in scripting the renaming where KB number is inside brackets by using () in delims but I am stuck at getting KB numbers from above mentioned kind of files. Somewhere KB numbers are between hyphens and somewhere between spaces.

Also the ERRORLEVEL starts giving faulty returncode when I try to use findstr or find command. It returns zero even if the KB word is found or not.
So I am looking for a quick fix for this requirement.
EDIT1: The script I used for finding KB numbers surrounded by brackets

@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2 delims=()" %%x in (D:\updates\list1.txt) do (
echo %%y

EDIT2: The code I am trying is:-

for /f "tokens=1-10 delims=-" %%a in (D:\updates\list2.txt) do (
echo %%c | find /I "kb"
echo Errorlevel for matching KB in %%c is- %ERRORLEVEL%
)

The file list2.txt contains(the example file names):

ie11-windows6.1-kb123456-x86_d43434342344ef.msu
IE8-windows6.0-KB234567-X86.msu
windows6.1-kb345678-x86_cae45678123_nov_17.msu

Currently I am targeting the filenames having hyphens. Once done I will script for filenames containing spaces. The EDIT2 script I created for just testing the errorlevel of find command. It will split words separated by hyphens and check for presence of a hyphen. But no matter what I do, even if it finds the match of KB word in separate words or not, ErrorLevel returned is zero. For simplicity right now I am just giving script which will pick third word and find kb in it. The third filename has no KB it the 3rd word, but the errorlevel for that filename is also zero.



Thanks
Kriss

user2593869
  • 123
  • 2
  • 10

2 Answers2

1

Your %errorlevel% issue is a delayed expansion problem.

Instead of processing each format on its own, you can do it all in one loop:

@echo off
setlocal enabledelayedexpansion

for /f "delims=" %%a in (D:\updates\list.txt) do (
  set "kb=%%a" 
  set "kb=!kb:*kb=KB!"
  for /f "delims=()-_ " %%b in ("!kb!") do set "kb=%%b"
  ECHO ren "%%a" "!kb!%%~xa"
)

First, assign the line to a variable to be able to do substring substitution.
Then replace "from the start to and including kb" (*kb) (1) with KB.
From that string, take the first part before any of the delimiters ()-_<space>.
Then rename the file %%ato the extracted KBxxxxxx' plus the original extension (%%~xa').

(1) thankfully (in this case), the substitution is not case sensitive. It handles all KB, kb, Kb and kB the same.

check the output before enabling the ren command by removing ECHO

Instead of a textfile (which you probably generated yourself just to be able to process it), you can process each of the files by changing the outer for to:

for /f "delims=" %%a in ('dir /b "D:\updates\*.msu"') do (
Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Stephan. Excellently worked. Thank you. It saved 3 days of manual work. Can you plz refer me to some blogs to understand about set parameters and advanced usage of delims parameters you used. – user2593869 Sep 28 '18 at 12:39
  • [Substring](https://ss64.com/nt/syntax-substring.html) and [replace](https://ss64.com/nt/syntax-replace.html). There is nothing "advanced" about [delims](https://ss64.com/nt/for_cmd.html). It's just a collection of chars that should serve as delimiter(s). I recommend to bookmark [SS64](https://ss64.com/nt) and visit it often. – Stephan Sep 28 '18 at 15:24
0

As two dots got lost on pasting to a comment here an answer:

I suggest to use a Powershell one line command from inside cmd:

powershell -nop -c "gci '*KB[0-9]*'|? Name -match '.*(KB\d+).*'|ren -newname {$Matches[1]+$_.Extension}" 

It uses a regular expression to grep KB and adjacent numbers.

The same a bit more verbose without aliases as a powershell script:

Get-ChildItem '.*KB[0-9].*' |
  Where-Object Name -match '.*(KB\d+).*' |
    Rename-Item -NewName {$Matches[1]+$_.Extension}" -WhatIf

Output with your samples and an appended -WhatIf parameter

> gci '*KB[0-9]*'|? Name -match '.*(KB\d+).*'|ren -newname {$Matches[1]+$_.Extension} -whatif
WhatIf: Ausführen des Vorgangs "Datei umbenennen" für das Ziel 
"Element: ie11-windows6.1-kb123456-x86_d43434342344ef.msu Ziel: kb123456.msu".
WhatIf: Ausführen des Vorgangs "Datei umbenennen" für das Ziel 
"Element: IE8-windows6.0-KB234567-X86.msu Ziel: KB234567.msu".
WhatIf: Ausführen des Vorgangs "Datei umbenennen" für das Ziel 
"Element: windows6.1-KB1234567 update for_IE10 for RCE.msu Ziel: KB1234567.msu".