Batch: find files with specific content and extend existing name - batch-file

I have about 100 .xml files, but its filenames are not self-explanatory. Therefore I would like to look for a specific word and extend the respecting file with this word.
Thanks to some other helpful entries, I could partially figure out how to do this, but somehow the files are not renamed.
Has anybody an idea what is wrong with my code? Thank you in advance.
chcp 1252
SET sourcedir=P:\path
FOR /f "tokens=1 delims=." %%a IN ('findstr /c:"3256" "%sourcedir%\*.xml"') DO (
ECHO (REN "%%a.xml" "%%a_3256.xml")
)
pause

chcp 1252
SET "sourcedir=P:\path"
FOR /f "delims=" %%a IN ('findstr /m /c:"3256" "%sourcedir%\*.xml"') DO (
ECHO REN "%%a" "%%~na_3256%%~xa"
)
pause
In your code you are using %%a for both arguments to ren command, but the second argument must only contain the name and extension, without path. You can solve it using %%~na, that is, the file name (without path or extension) of the file being referenced by %%a (%%~xa is the extension)
Also, if the string is found more than once in any file, your code will try to rename the file twice (or more). It is better to use the /m switch in findstr to only retrieve the list of files.
Rename operations are only echoed to console. If the output is right, remove the echo command.

Dang it MC ND, right after I did some frankenstein scripting, coming up with:
After trial and error along with this great website, I managed to come up with (giving credit to DOS Batch : remove characters from string in a FOR loop )
#ECHO OFF
set pathd=C:\SomePathHere
setlocal enabledelayedexpansion
for /f %%a in ('findstr /ic:SearchString %pathd%\*.xml') do (
set str=%%a
set str=!str:^:=!
echo !str!
)

Related

Removing certain parts of a files name using cmd

I've been attempting to remove a certain string from a bunch of files but I am unable to do it. The part I want to rename is the .english in my files. How would I do this?
https://i.stack.imgur.com/rhRKG.png
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following setting for the source 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"
FOR /f "delims=" %%b IN (
'dir /b /a-d "%sourcedir%\*.english.*" '
) DO (
SET "newname=%%b"
ECHO REN "%sourcedir%\%%b" "!newname:.english.=.!"
)
GOTO :EOF
Always verify against a test directory before applying to real data.
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.
Because your string splitting is at periods, ., I'd offer the following methodology.
In cmd.exe:
for %g in ("*.english.wav") do #for %h in ("%~ng") do #ren "%~g" "%~nh%~xg"
From a batch file:
#For %%G In ("*.english.wav") Do #For %%H In ("%%~nG") Do #Ren "%%~G" "%%~nH%%~xG"
As your question is unclear as to the intended final filename.
If you wanted to replace .english with something else, lets say .german, rather than simply removing it, then change:
"%~nH%~xG", or "%%~nH%%~xG"
To:
"%~nH.german%~xG", or "%%~nH.german%%~xG"

How to find and replace part of filenames from list

I have a list of files that I need to rename at the same part of each file, with different values.
Example:
BL_1402B103_abc.wav > BL_C1234-1_abc.wav
BL_15489B59_abc.wav > BL_C1234-5_abc.wav
So in the first example above I want to replace the 1402B103 with C1234-1 all the files are the same length and the sections I want to replace are separated by "_".
I have some code for finding/replacing parts of a filename but I need to do this for hundreds of files - is there a way to pull Pattern= & Replace= as variables from a csv/list and run as a batch?
Setlocal enabledelayedexpansion
Set "Pattern=1402B103"
Set "Replace=C1234-1"
For %%f in (*.wav) Do (
Set "File=%%~f"
Ren "%%f" "!File:%Pattern%=%Replace%!"
)
You could create a csv file and add your search/replace strings:
myfile.csv
1402B103,C1234-1
15489B59,C1234-5
etc,etc
The batch file, myrename.cmd
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1,* delims=," %%i in (myfile.csv) do (
set "search=%%i"
set "replace=%%j"
call :fix
)
exit /b
:fix
for %%a in (*!search!*.wav) do (
set "file=%%a"
set "file=!file:%search%=%replace%!!"
echo ren "%%~fa" "!file!"
)
It will seatch for each string in the csv file, split by comma assign the first meta variable to the search variable and the second to the replace variable. Then we simply do the replace for each by calling that procedure.
Note!! in this instance I used echo before ren for testing results. Only once you are happy with your results should you remove echo to perform the actual command.
I would do such a multi-rename operation of files using shareware Total Commander with its built-in multi-rename tool which has a every easy to use graphical user interface for such tasks making it possible to review the new names of the files before executing the rename operation. This file rename operation could be done with Total Commander nearly complete using only some mouse clicks, just C1234- need to be typed on keyboard. And Total Commander supports even an undo if the rename operation fails for some reason.
Let us assume C1234- in new file name is a fixed sequence of characters and 1 and 5 is a number incremented by one on each renamed each file.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "FileNumber=1"
for /F "eol=| delims=" %%I in ('dir BL_????????_abc.wav /A-D-H /B /ON 2^>nul') do (
move /Y "%%I" "BL_C1234-!FileNumber!_abc%%~xI" >nul
set /A FileNumber+=1
)
endlocal
This solution works for the example.
But what about string left to first underscore and string right to second underscore vary from file name to file name?
In this case the following batch file could be the right solution:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "FileNumber=1"
for /F "eol=| delims=" %%I in ('dir *_????????_*.wav /A-D-H /B /ON 2^>nul') do (
for /F "eol=| tokens=1,2* delims=_" %%A in ("%%~nxI") do (
move /Y "%%I" "%%A_C1234-!FileNumber!_%%C" >nul
)
set /A FileNumber+=1
)
endlocal
The command MOVE with option /Y is used instead of command REN to make the file rename even on a file with that name is already existing. Total Commander would inform the user about such an issue on renaming files with other files with new name already existing.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?
echo /?
endlocal /?
for /?
move /?
set /?
setlocal /?
Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
Batch solutions just make it hard to know what to do.
Batch is far too unreadable for my liking. %% and ! and !! in weird places. Bah.
You are better off making a C# console app that gives you 2 prompts and just does it, like I did.
In any case, what is being demonstrated is, for each file, you grab that filename as a string variable, and do all the string replacements in that string variable. Then you rename the file, or in C# it's MoveTo(newPath), the resulting string variable.

I need to create a list of folders that contain a specific file type with a batch file

Using a batch file I'm trying to generate a list of only folders within a location that contain a certain file type, let's call it *.abc
at the moment I only know how to echo a DIR command output to a file called folder.lst, I would like to expand on that and try to either
a) echo only folders containing the *.abc file type to folder.lst
b) remove references in folder.lst of folders that do not contain the *.abc file type.
I also tried having a FOR loop check each line to see if a *.abc file existed in that location and skip it, if not, but I just could not get that to work, here is an example of what I had.
setlocal enableextensions enabledelayedexpansion
FOR /F "delims=" %%C in (folder.lst) do (
set temp=%%C
if not exist !temp!\*.abc (goto skip) else (goto resume)
:resume
then my actions live here
:skip
)
but I am aware I am doing something wrong here...I just do not know what.
Maybe the /R form of the for command will help:
for /r "basedir" %%a in (.) do if exist "%%~a\*.abc" (
echo %%a contains .abc file(s)
)
The %%a will be the directories you want (with a trailing \., but you should be able to not care or accommodate this).
There are problems with such of the script as you have posted in that you can'y use labels within a block statement. You've also not provided any examples.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "lastdir="
FOR /r "%sourcedir%" %%a IN (*.abc) DO IF "!lastdir!" neq "%%~dpa" (
SET "lastdir=%%~dpa"
ECHO %%~dpa
echo "!lastdir:~0,-1!"
)
GOTO :EOF
Each directory found will be echoed twice - one with the trailing \ and once without.
You would need to change the setting of sourcedir to suit your circumstances.
#echo off
setlocal enableextensions disabledelayedexpansion
set "root=%cd%"
for %%a in ("%root%") do for /f "delims=: tokens=2" %%b in ('
dir /a-d /s "%root%\*.abc" ^| find "\"
') do echo(%%~da%%~pnxb
This executes a recursive dir command searching for the indicated file type under the starting point (change root variable to suit your needs). For each found folder we retrieve the folder from the dir header that precedes the file list (the lines that contain a backslash).
To separate the path from the rest of the information in the line, the colon is used as delimiter. As this will leave the drive out of the retrieved information, an aditional for is used to retrieve the drive from the folder reference.
From the command line:
for /f "delims=" %a in ('dir /s /b *.abc') do echo %~dpa >> folders.lst
In a batch file:
for /f "delims=" %%a in ('dir /s /b *.abc') do echo %%~dpa >> folders.lst
The above commands will place only the folder names containing the *.abc files in folders.lst.
Notes:
% should be replaced by %% when the command is used in a batch file.
The ~dp part of %~dpa expands %a to a drive letter and path only. Remove the d if you don't want the drive letter. The p path includes a trailing \ which may be interpreted as an escape character by some commands.
The above commands start the search in the current directory. To search from the root of the current drive you can do cd \ first.
For more information see FOR /F Loop command: against the results of another command and Parameters.

Batch find certain filenames then use the names in variable

I need help with a script that first finds all files in a directory with a certain string, then uses the filenames in a variable to be used in a script.
So:
Find files and filenames
Saves file?
Start some kind of loop? that changes a variable then executes the
belonging script
Repeat till all filenames have been used.
My code here..
#Echo off
For /r C:\work %%G In (*) Do #Findstr /M /S "string" > filenames.txt %%G
Set Var1=0
For %%G In (*) Do (
Var1=<filenames.txt (???)
script
script
I haven't writen "script" myself and friend help me with it, if you would like to see it do you need to wait until I can get to my other computer at home.
Thanks on beforehand!
Find files and filenames
Saves file
set "search=what I want to find"
(for /f "delims=" %%a in ('dir /a-d /b /s "C:\work" ^| findstr "%search%"') do echo (%%~fa)>filenames.txt
Start some kind of loop? that changes a variable then executes the belonging script
Repeat till all filenames have been used.
for /f "delims=" %%a in (filenames.txt) do (
REM here do something inside the loop
REM until all file names from filenames.txt were processed
)
This is designed to find files in c:\work that match a string, and echo the filenames.
#echo off
cd /d "c:\work"
for %%a in ("*string*") do (
echo "%%a"
)

.bat - check for a string in file

I have a xml files filles with tabs and spaces. I am trying to search for a string in this file. File is something like below. I am trying to search for </ViewSettings> and this surrounded by tabs and spaces.
<ViewSettings>
<Location>
<X>0</X>
<Y>0</Y>
</Location>
</ViewSettings>
<WorkspaceName="FREE_UST_BETA_UA" PAth="\\mktxindfs\data_configuration\FREE_BETA" IsAdmin="false" />
</Workspaces>
I have the code below
echo off
setlocal enabledelayedexpansion
for %%X in (C:\add\WorkspaceXML\Workspaces.xml) do (
set "reference=</ViewSettings>"
for /f "delims=" %%T IN (%%X) do (
set output=%%T
echo output:!output!
if !output!==!reference! echo found reference.....
)
)
It does not print "found reference"
Thanks
Have you considered building your batch file off of findstr instead? This command would tell you if the string was in the file by reporting the filename.
findstr /M /c:"</ViewSettings>" C:\add\WorkspaceXML\Workspaces.xml
EDIT
If you use findstr /N /O ... instead, you can get the line number and offset of the match(es), maybe that will be of more use to you. The output in your case above would be
6:69:</ViewSettings>
EDIT 2
Proper offset added above thanks to dbenham. Not sure if the offset is still of use to you, but to get both values in vars, try this:
FOR /F "tokens=1,2 delims=:" %%a in ('findstr /N /O /c:"</ViewSettings>" C:\add\WorkspaceXML\Workspaces.xml') do echo %%a %%b
This just displays the vars for you of course, but you can set them as needed.

Resources