I'm making batch-files for fun and i ran in to a problem. I've search for a solution and i havn't found anyone.
I'de like to code my batch file so it will search for a specific file on my c: drive and after it found the pathlocation I want it to execute. Can it be done?
I don't know if i can combine the path I get from "dir tool.exe /s /p" somehow.
Using batch
for /f %%i in ('dir C:\tool.exe /s /b') do (
start %%~fi
exit /b
)
Consider the fact that if your executable is located deep down the folder tree it will take some time to actually find it and run. So if you want to improve the performance you might narrow down a search a bit if it is an option of course.
Try this:
for /f "delims=" %%A in ('dir tool.exe /s /p') do set "var=%%A"
start %var%
The output of 'dir tool.exe /s /p' is saved in var which you can then use to do whatever you need to do.
I know you asked for batch, but here is as a powershell option because I was bored:
Get-ChildItem / -Recurse -File | % { if($_.Name -eq "notepad.exe") { &$_.FullName; break} }
It will execute the first hit on the search for "notepad.exe" and then exit the script.
Related
I can use dir /s /b *.Tests.*.dll to recursively find all files that match that pattern, but I need to also find them only if they are in \bin\Debug\ instead of \obj\Debug\ or \bin\Release.
So I tried this command:
dir /s /b Tests\Unit\*\Debug\bin\*.Tests.*.dll
But it fails with The filename, directory name, or volume label syntax is incorrect.
I couldn't find any previous SO question that addresses this problem but if one exists please point it to me.
Is there any way to achieve the desired result (apply filter on entire path)? My intent is to use the list to run NUnit on each unit test assembly in my project under jenkins using this command from Use NUnit Console Runner to run all tests under a folder
for /f %%f in ('dir .\test\ /b /s *.Test.dll') do nunit-console /nologo /noshadow /framework:net-4.0 /xml:.\test\TestResults.xml "%%f"
On linux I would have used ls -r ... | grep ... | xargs ... and I'm trying to achieve something similar here.
I only need to apply this additional filter on the parent folders as well. If it's not possible I'll have to use PowerShell.
FOR /d %%a IN ("%sourcedir1%\*") DO DIR /s /b "%%~a\%sourcedir2%\*.exe" 2>nul
where sourcedir1 is the part of the required path before the \*\ and sourcedir2 the part after.
simply assign each dirname in turn to %%a and use that as the start point for the second dir
I found DOS batch script with for loop and pipe, and using the idea there I constructed this command:
for /f %f in ('dir /s /b Tests\Unit ^| findstr \\bin\\Debug\\.*\.Tests\..*\.dll$"') do echo %f
No I only need to replace %f with %%f for batch files, and I can replace echo %f with the command to run nunit.
My current folder structure goes as follows:
E:\Videos\Movies\Random Folder Name\Subs\Random File Name.srt
I would like to move my .srt files up one level so it reads:
E:\Videos\Movies\Random Folder Name\Random File Name.srt
I would prefer this to be a .bat file, but am willing to use PowerShell.
~EDIT~
I found something online that partially works and edited it to my needs:
#echo off
set thisdir=%cd%
for /f "delims=" %%A in ('dir /b /ad') do (
cd /d "%%~dpnA"
for /f "delims=" %%B in ('dir /b /ad') do (
echo Level 2 Directory: %%~dpnB
cd /d "%%~dpnB"
for /f "delims=" %%C in ('dir /b /ad') do (
echo Level 3 Directory: %%~dpnC
cd /d "%%~dpnC"
move *.srt ..\
cd..
rd "%%~dpnC"
)
)
)
This works, but only for the first folder, I can't seem to make Level 2 recursive as that is the level with random movie names. I tried replace for /f with for /r, but it was a no go.
Here's a one-liner:
forfiles /m *.srt /s /c "cmd /c move #file .."
Full code (you can run this from any drive now):
#echo off
cd /d E:\Videos\Movies\
for /r %%i in (*.srt) do move "%%~dpnxi" "%%~dpi.."
pause
This looks for all files with type .srt and moves them to the folder it was found in -1 directory (%%~dpi is the directory it was found in, adding .. to a path removes the last directory, so C:\Users\.. would put you at C:\).
PS: This time I have tested this, and it works.
Although the answers already given work, I still wanted to try and figure out how to perfect the code to my exact needs. Couldn't accomplish this with CMD, so I looked into powershell (which was easier for me to grasp for some reason) and coded this:
$sourcefolder = "F:\Videos\Movies\*\Subs\"
$files = Get-ChildItem -Recurse $sourcefolder | where {$_.PSIScontainer -eq $false}
foreach ($file in $files)
{
$destinationFolder = Split-Path -Parent $file.Directory.FullName
move-item $file.FullName $destinationFolder
}
It doesn't specify .srt files, but they are the only extension located in that folder. Thank you for the help guys!
I have almost the final command line, but I need the rename part of it, to reach the goal I want I have this:
for /f “tokens=*” %a in (‘dir /b /s /a-d’) do #copy “%a” “C:\YourFolder” /y
and it works fine, but in my case I have tons of folders with only one file on each one, this file has the same name file.ext, so, is there any way to move and change the name, for example like file1.ext, file2.ext,...
Thanks!
This is not foolproof but it's likely to work, and will prompt if the small likelihood occurs that a filename exists. You'll need a batch file to make it foolproof and to improve the naming strategy.
Remove the #echo if you are happy with the result.
cmd /v:on /c for /f "delims=" %a in ('dir /b /s /a-d') do #echo copy “%a” “C:\YourFolder\%~na-!random!!random!!random!%~xa” /-y
I just want to know how can I get all the names of the folders in a current directory. For example in my current directory I have three folders:
stackoverflow
reddit
codinghorror
Then when I execute my batch script all the three folders will print in the screen.
How can I achieve this?
Using batch files:
for /d %%d in (*.*) do echo %%d
If you want to test that on the command line, use only one % sign in both cases.
On Windows, you can use:
dir /ad /b
/ad will get you the directories only
/b will present it in 'bare' format
EDIT (reply to comment):
If you want to iterate over these directories and do something with them, use a for command:
for /F "delims=" %%a in ('dir /ad /b') do (
echo %%a
)
note the double % - this is for use in a batch, if you use for on the command line, use a single %.
added the resetting of default space delims in response to #Helen's comment
With PowerShell:
gci | ? { $_.PSIsContainer }
Old Answer:
With PowerShell:
gci | ? {$_.Length -eq $null } | % { $_.Name }
You can use the result as an array in a script, and then foreach trough it, or whatever you want to do...
For getting all the subfolders of a specific directory and display it in CMD :
#echo off
dir C:\input /s /b /o:n /a:d
Pause&Exit
For getting all the subfolders of a specific directory and save it in a text file :
dir C:\your_directory /s /b /o:n /a:d > output.txt
I have directory structure:
DIR
|-UNINSTALL.BAT
|-component_name
|-source
|-setup.exe
|-uninst.bat
|-another_component_name
|-source
|-setup.exe
|-uninst.bat
|-yet_another_component_name
|-source
|-setup.exe
|-uninst.bat
and so on...
In every directory like "component_name" I have setup.exe file which installs current component to the palette component in Delphi.
uninst.bat contains only this string:
"setup.exe" /uninstall
So I need to write UNINSTALL_ALL.bat in DIR that would run the uninst.bat in all component directories.
Thank you in advance.
you could do it with this line:
for /f %%a in ('dir /b /s uninst.bat') do call %%a
note that the '%%' is necessary for batch files. if you are testing this on the command line, only use one '%'
That is kind of akward in a batch file. Though you could probably do it with the foreach statement. I would suggest though that you have a look at Powershell which will definitely give you the power to do this simply and a whole lot more if you want it.
You want to use the "for" construct. Something like this:
for %%i in (component_name another_component_name yet_another_component_name) do %%i\uninst.bat
The double-escaping (%%) is necessary if you put the "for" loop in a batch file. If you are just typing it out in a command prompt, only use 1 %.
Also, you may be able to use a wildcard to match against the directory names, if they follow some convention. Open up a command prompt and run "for /?" to see everything it can do...I believe there is a /d option to match against directories. That would look something like:
for /D %%d in (component_*) do %%d\uninst.bat
(obviously, adjust the wildcard to match your component directories.)
This should work:
FOR /F %%a IN ('dir /b /s uninst.bat') DO START /B %%a
if you want them to wait each other, use this:
FOR /F %%a IN ('dir /b /s uninst.bat') DO START /B /WAIT %%a
The way you describe your problem, you have only one level of sub-directories and you always call the same batch, from the root. Therefore:
Uninstall_all.cmd
#echo off
for /F "delims=" %%d in ('dir /b /ad') do cd "%%d"& start /b /w ..\uninstall.bat& cd ..
Should do the trick.