Script for finding folder that contains a file - windows

I'm working on a portable development enviroment, so I need to find the route of the bins.I have tried with this:
for /f "tokens=*" %%a in ('dir mysqld.exe /b /s') do set mysql=%%a
It returns A:\test\mysql-5.7.24-winx64\bin\mysqld.exe but I want to get only the folder, like this A:\test\mysql-5.7.24-winx64\bin\, how can I achieve this?.

use modifiers (described in for /?):
for /f "tokens=*" %%a in ('dir mysqld.exe /b /s') do set "mysql=%%~dpa"
echo %mysql%
%%~dpa returns drive and path only.
Same without using dir (as for /r can recursively search for (a) file(s)):
for /r "c:\startfolder" %%a in (mysqld.exe) do set "mysql=%%~dpa"
"c:\startfolder" is the start point for recursive search (you can omit it to search within the current folder and it's subfolders)
Note: if more there is than one matching file, the variable will hold the last finding.

Use a subroutine with a parameter.
read about parameters here
Something like this. Remove what I added for display.
#echo off
for /f "tokens=*" %%a in ('dir mysqld.exe /b /s') do call :GetFolder "%%a"
echo(%mysql%
pause
goto :eof
:GetFolder
REM 1=Filespec
set "MySQL=%~dp1"
goto :eof

Related

How to batch rename files in windows removing everything from them but set of listed strings?

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.

Getting Parent Directory for each file from Dir Output

I have a directory with multipe levels of folders.
I am completely new to writing batch files and I am writing my first one.
Stuck for ages on trying to
find all files in the directory including sub-folder
get parent directory for each file
save as variable like %parent.filename%
I have been searching here:
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490909(v=technet.10)
And on Google but unfortunately I am stuck.
So now I managed to save the full path of each file as variable, but I want %Folder.FileName% to return the parent directory only, not the full path.
This is the code I have been testing in the command prompt.
For /F %A in ('Dir Linkedin /A-D /s /b /o') do SET Folder.%~nxA=%~pA
EDIT
I also saw this thread
And tried this code:
FOR /F %A in ('Dir Linkedin /A-D /s /b /o') do ECHO %~nxA %~pA >>Paths.txt
FOR /F "tokens=1,2" %A in (Paths.txt) do SET Parent.%A=%~nB
But %~nxB doesn't return any value... I expected it to get the last string of the path.
FOR /F %A in ('Dir Linkedin /A-D /s /b /o') do ECHO %~nxA %~pA. >>Paths.txt
FOR /F "tokens=1,2" %A in (Paths.txt) do SET Parent.%A=%~nB
Note the extra .
The path provided by the ~p modifier terminates in \ so adding . to this means "the directory name itself as though it was a filename"
As a one-line command (within a batch, decorated by standard palaver)
#ECHO OFF
SETLOCAL
FOR /F %%A in ('Dir test* /A-D /s /b /o') do FOR /F %%S in ("%%~pA.") do SET Parent.%%~nxA=%%~nS
set parent.
GOTO :EOF
I used the filemask test* to better suit my system.
I can't imagine you'd voluntarily perpetually re-type the command, so the format for use within a batch file is shown.
I would suggest you do this as a single nested For loop from the Command Prompt and with no output file:
For /F "Delims=" %A In ('Dir /B/S/A-D "Linkedin" 2^>NUL')Do #For %B In ("%~pA.")Do #Set "Folder.%~nxA=%~nxB"
From a batch-file, perhaps this would help you out:
#Echo Off
Rem Remove any existing Folder. variables
For /F "Tokens=1*Delims==" %%A In ('Set Folder. 2^>NUL')Do Set "%%A="
Rem Set the new variables
For /F "Delims=" %%A In ('Dir /B/S/A-D "Linkedin" 2^>NUL')Do For %%B In ("%%~pA.")Do Set "Folder.%%~nxA=%%~nxB"
Rem View any returned variables
Set Folder. 2>NUL&&Pause

Copy all files except the last modified file to a new directory

I need to move files from c:\prueba1 to c:\prueba99 but I don't know how to make a comparison betweeen all files in the source directory (c:\prueba99) to move all files in the directory with the exception of the last modified file in the directory. I know there is a wmic command with get InstallDate, LastModified, but I don't know the ms-dos syntaxis to asign a variable and compare it to know that one file readed is the last modified
I found an example:
for /f "delims=" %%A in ('wmic datafile where "drive = 'c:' and path='\\windows\\'"
get LastModified^,Name /format:table^|find ":"^|sort /r') do #echo %%A
And tried to modify it with no result because it appears to just list the datafile names but not the files themselves.
This is my modified version:
for /f "skip=1 delims=" %%A in ('wmic datafile where "drive = 'c:' and path='\\prueba1\\'"
get LastModified^,Name /format:table^|find ":"^| sort/r') do move (%%A) c:\prueba99
for /f "skip=1 delims=" %%a in ('dir /b /tw /o-d /a-d c:\prueba1\*.*'
) do move "c:\prueba1\%%a" "c:\prueba99"
dir command get the files in descending creation date order, so the first is the latest. for command iterates over this list, skipping the first one, moving the files to the target folder.
A way to ge the last modified file :
#echo off
set $path=c:\prueba99
for /f %%a in ('dir/b/a-d/o-d "%$path%"') do (
set $Last=%%a
goto:next)
:next
echo Last modified : [ %$Last% ]
This should work for you and it also allows you to discard as many NEWEST files as you want (for your case I've taken 1):
#echo off
setlocal
:: change the next two statements to match what you want
set srcdir=C:\prueba1
set tgtdir=C:\prueba99
if not exist %tgtdir%\*.* md %tgtdir%
set ctr=0
for /f "tokens=*" %%a in ('dir "%srcdir%" /o-d /b') do call :maybemove "%%a"
set /a ctr-=3
echo %~n0: %ctr% files were moved from %srcdir% to %tgtdir%
endlocal
goto :eof
::--------------------
:maybemove
:: increment counter and bypass the ONE newest file
set /a ctr+=1
if %ctr% leq 1 goto :eof
:: remove the double-quotes from the front and back of the filename
set fn=%~1
:: perform the move
move /y "%srcdir%\%fn%" "%tgtdir%"
goto :eof

How to create file in partially known folder name using batch file

I want to create a 0 byte file names dblank in a specific directory C:\Users\myUser\*.data\.
echo. 2>"C:\Users\myUser\*.data\dblank.txt"
The * sign in the above command refers to any letters or numbers. I do not know. How can I refer to any letters or numbers in my batch code?
Maybe this:
setlocal enableextensions
for /D %%i in (C:\Users\myUsers\*.data) do copy nul "%%~i\dblank.txt"
endlocal
You can omit setlocal/endlocal if command extensions are already enabled (cmd /E:on).
This works on every existing *.data folder, if any.
#echo off
for /f "delims=" %%f in ('dir /b /s /ad C:\Users\myUser\*.data') do echo. 2>"%%f\dblank.txt"
EDIT
Filter results:
#echo off
for /f "delims=" %%f in ('dir /b /s /ad C:\Users\myUser\*.data^|findstr /r "\\[0-9a-zA-Z]*\.data$"') do (
echo. 2>"%%f\dblank.txt"
)

Batch rename files how to loop in order of filename?

I have a bunch of jpg files named IMG_0001, IMG_0002, etc. The problem was that there I had to delete a couple of them, so I need to rename the files to fill in the gaps. In essence,
IMG_0001, IMG_0002, IMG_0004, IMG_0006
are renamed
IMG_0001, IMG_0002, IMG_0003, IMG_0004.
Thus filling in the gaps caused by the files I deleted. However, the bat file I wrote to do this sometimes jumbles the files out of order, so what was originally IMG_0001 would become IMG_0002, and IMG_0003 would become IMG_0001. How can I ensure that my bat file loops through the files in order of name?
This is my bat file:
#echo off
set i=1
set y=0000
for %%f in (*.jpg) do call :renameit "%%f"
goto done
:renameit
set x=%y%%i%
ren %1 IMG_%x:~-4%.jpg
set /A i+=1
:done
I don't think FOR supports ordering on its own, but DIR does with the /on ("order by name") switch. So, try replacing your FOR loop with this:
for /f "tokens=*" %%f in ('dir /b /on *.jpg') do call :renameit "%%f"
#echo off
setlocal enableextensions enabledelayedexpansion
for /f "tokens=1,* delims=:" %%a in ('dir /a-d /on /b "IMG_*.jpg"^|findstr /n "^"') do (
set /a "n=%%a+10000"
ren "%%b" "IMG_!n:~-4!.jpg"
)
This just uses findstr to numerate the list of retrieved files (each lines is in the format number:filename) and uses this numeration to do the rename of files.

Resources