Batch file to list all subfolder paths - windows

I am trying to write a command that runs from location of the program. The program asks user to type in a folder to search for, when the folder is found, I need a list of directories to its subfolders. Below is my code so far:
ECHO OFF
ECHO Enter name for your target search folder
SET /P searchf=[Please type desired search forder]
for /d %%a in ("%searchf%".) do dir /ad /on /s /b "%%a" >> %searchf%.txt
GOTO End
:End
Assuming the target folder is called "test", I want to have a result like this:
C:\Users\IT\test\pany\all
C:\Users\IT\test\ondy\part\clear
C:\Users\IT\pany\test\check\apps
C:\Users\IT\pand\all\check\test
So far my code returns dir till where the "test" was found.

As JosefZ pointed out, wild cards will help:
ECHO OFF
ECHO Enter name for your target search folder
SET /P searchf=[Please type desired search forder]
dir /ad /on /s /b "*%searchf%*"
Since there is only one search term, you do not need a for loop.
Using a variable file name I considered difficult, that's why I first changed it to be a fixed filename, until I figured out that for having a list of directories on the screen you can use the dir output directly.

Related

Batch file that searches for a folder with the same name as a local file and moves said file to the located folder not working

So I am trying to create a batch file that will take a pdf file in the same directory as the batch file and output the file name (sans extension). I used this code to accomplish this:
#echo off
for /r "C:\Users\me\Test Folder" %%G in (*.pdf) do set "name=%%~nG"
This works fine. The next step is to search another directory and find a directory within the searched directory whose name matches the output of the above code (stored in the %name% variable). Here's what I tried:
dir "P:\Accounting\Acc Pay" | find %name% | set "loc=%%~dp"
The goal of the above code was to find only the directories that had the same name as the original pdf file and then set the drive and path of the output to a variable %loc%. I think this is where I messed up.
Once the path to the folder is set to %loc%, I then am supposed to finish with this line:
move .\*.pdf %loc%
This would take all the pdf files (there will only be one in the directory at once) in the directory with the batch file and move it to the path currently stored in the %loc% variable.
In total the code looks like this:
#echo off
for /r "C:\Users\me\Test Folder" %%G in (*.pdf) do set "name=%%~nG"
for /r %%A in ('dir "P:\Accounting\Acc Pay" | find %name%') do set "loc=%%~dpA"
move .\*.pdf %loc%
However, the code seems to move the pdf file into the same location it was already in (ie the folder with the batch file). I assume the %loc% variable is not working properly. Any help much appreciated.
Like #Magoo said (^|). And you surely want to add the following switches for the dir command: /b for "bare format" (name only) and /ad for "Attribute Directory" to return folder names only. find needs its's argument quoted, and for safety, the destination for the move command should also be quoted. Your find could benefit from /i to make it case-insensitive.
I personally would do it with nested loops to avoid creating superflouos variables:
#echo off
for /r "C:\Users\me\Test Folder" %%G in (*.pdf) do (
for /r %%A in ('dir /b /ad "P:\Accounting\Acc Pay" ^| find /i "%%~nG"') do (
move "%%G" "%%~dpA"
)
)
Bonus: should there be more than one .pdf file (maybe after the Weekend or Holidays), this would process all of them correctly in one go.
Depending on your naming structures, consider replacing find /i "%%~nG" with findstr /iblc:"%%~nG" (see findstr /?to find out what the switches mean)
(Note to prevent confusion: findstr is the only command (as far as I'm aware) that supports concatenating switches into one. /iblc is the same as /i /b /l /c)

How to list all folders on specified drives with folder name first then gap then full path to folder?

dir i:\ j:\ k:\ /b /s /a:-D >c:\Users\Jason\Desktop\allFolderFilesOn_I_J_K.txt
This works great, but I am after a custom output, foldername full_path
Is this possible and if so how do I achieve this?
If I understand correctly, you don't want any files, but for every folder instead of C:\windows\system32 you want an output like system32 C:\Windows\
This can be done with the following command:
(for /d /r "D:\" %a in (*) do #echo %~nxa %~dpa)>c:\Users\Jason\Desktop\allFolderFilesOn_I_J_K.txt
where /d means "Directories only"
/r "Recursive" ("down the folder tree")
"D:\" the starting point
%~nxa the last element (the folder name)
%~dpa the drive/path to the folder
Note: this is command line syntax. For use in a batch file, replace each % with %%

How to execute an application existing in each specific folder of a directory tree on a file in same folder?

I have some folders with different names. Each folder has a specific structure as listed below:
Folder1
Contents
x64
Folder1.aaxplugin
TransVST_Fixer.exe
Folder 2
Contents
x64
Folder 2.aaxplugin
TransVST_Fixer.exe
There are two files within each subfolder x64. One file has the same name as the folder two folder levels above. The other file is an .exe file whose name is the same in all folders.
Now I need to run file with file extension aaxplugin on each specific .exe file. It would be obviously very time consuming opening each and every single folder and drag & drop each file on .exe to run it on this file.
That's why I am trying to create a batch script to save some time.
I looked for solutions here on Stack Overflow. The only thing I have found so far was a user saying this: When I perform a drag & drop, the process 'fileprocessor.exe' is executed. When I try to launch this exe, though, CMD returns error ('not recognized or not batch file' stuff).
How can I do this?
UPDATE 12/22/2015
I used first a batch file with following line to copy the executable into x64 subfolder of Folder1.
for /d %%a in ("C:\Users\Davide\Desktop\test\Folder1\*") do ( copy "C:\Program Files\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%a\x64\" 2> nul )
After asking here, I tried the following script:
for /f "delims=" %%F in ('dir /b /s x64\*.aaxplugin') do "%%~dpFTransVST_Fixer.exe" "%%F"
Unfortunately, the output is as following
C:\Users\Davide\Desktop>for /F "delims=" %F in ('dir /b /s x64\*.aaxplugin') do "%~dpFTransVST_Fixer.exe" "%F"
The system cannot find the file specified.
Try the following batch code:
#echo off
setlocal EnableDelayedExpansion
for /R "%USERPROFILE%\Desktop\test" %%F in (*.aaxplugin) do (
set "FilePath=%%~dpF"
if not "!FilePath:\x64\=!" == "!FilePath!" "%ProgramFiles%\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%F"
)
endlocal
The command FOR with option/R searches recursive in all directories of directory %USERPROFILE%\Desktop\test being expanded on your machine to C:\Users\Davide\Desktop for files with file extension aaxplugin. The loop variable F contains on each loop run the name of the found file with full path without surrounding double quotes.
The drive and path of each found file is assigned to environment variable FilePath.
Next a case-sensitive string comparison is done between file path with all occurrences of string \x64\ case-insensitive removed with unmodified file path.
Referencing value of environment variable FilePath must be done here using delayed expansion because being defined and evaluated within a block defined with ( ... ). Otherwise command processor would expand %FilePath% already on parsing the entire block resulting in a syntax error on execution because string substitution is not possible as no environment variable FilePath defined above body block of FOR loop.
The strings are not equal if path of file contains a folder with name x64. This means on provided folder structure that the file is in folder x64 and not somewhere else and therefore the application is executed next from its original location to fix the found *.aaxplugin file.
The line with IF is for the folder structure example:
if not "C:\Users\Davide\Desktop\test\Folder1\Contents" == "C:\Users\Davide\Desktop\test\Folder1\Contents\x64\"
if not "C:\Users\Davide\Desktop\test\Folder 2\Contents" == "C:\Users\Davide\Desktop\test\Folder 2\Contents\x64\"
So for both *.aaxplugin files the condition is true because the compared strings are not identical
Also possible would be:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%F in ('dir /A-D /B /S "%USERPROFILE%\test\*.aaxplugin" 2^>nul') do (
set "FilePath=%%~dpF"
if not "!FilePath:\x64\=!" == "!FilePath!" "%ProgramFiles%\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%F"
)
endlocal
But command DIR is not really necessary as it can be seen on first provided code.
But if the application TransVST_Fixer.exe for some unknown reason does its job right only with directory of file being also the current directory, the following batch code could be used instead of first code using the commands pushd and popd:
#echo off
setlocal EnableDelayedExpansion
for /R "%USERPROFILE%\test" %%F in (*.aaxplugin) do (
set "FilePath=%%~dpF"
echo !FilePath!
if /I "!FilePath:~-5!" == "\x64\" (
pushd "%%~dpF"
"%ProgramFiles%\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%~nxF"
popd
)
)
endlocal
There is one more difference in comparison to first code. Now the last 5 characters of path of file are compared case-insensitive with the string \x64\. Therefore the file must be really inside a folder with name x64 or X64. A folder with name x64 or X64 anywhere else in path of file does not result anymore in a true state for the condition as in first two batch codes.
But if for some unknown reason it is really necessary to run the application in same folder as the found *.aaxplugin and the directory of the file must be the current directory, the following batch code could be used:
#echo off
setlocal EnableDelayedExpansion
for /R "%USERPROFILE%\test" %%# in (*.aaxplugin) do (
set "FilePath=%%~dp#"
if /I "!FilePath:~-5!" == "\x64\" (
pushd "%%~dp#"
"%%~dp#TransVST_Fixer.exe" "%%~nx#"
popd
)
)
endlocal
The path of the file referenced with %%~dpF always ends with a backslash which is the reason why there is no backslash left of TransVST_Fixer.exe (although command processor could handle also file with with two backslashes in path).
In batch code above character # is used as loop variable because %%~dp#TransVST_Fixer.exe is easier to read in comparison to %%~dpFTransVST_Fixer.exe. It is more clear for a human with using # as loop variable where the reference to loop variable ends and where name of application begins. For the command processor it would not make a difference if loop variable is # or upper case F.
A lower case f would work here also as loop variable, but is in general problematic as explained on Modify variable within loop of batch script.
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 /?
if /?
popd /?
pushd /?
set /?
setlocal /?
Your question isn't quite clear, but it seems, something like this should work:
for /f "delims=" %%f in ('dir /b /s X64\*.ext') do "%%~dpfMyExe.exe" "%%f"
Maybe you have to change directory to each folder (depends on your .exe):
for /f "delims=" %%d in ('dir /B /ad') do (
pushd "%%d"
for /f "delims=" %%f in ('dir /b "contents\x64\*.ext"') do (
cd Contents\x64
MyExe.exe "%%f"
)
popd
)
Assuming:
The Directory structure is fixed and the files are indeed in a subfolder contents\X64\.
MyExe.exe is the same (name) in every folder.
There is only one file *.ext in every folder.
I'll give you the script I created for doing so, hope it works for you
for /d %%d IN (./*) do (cd "%%d/Contents/x64" & "../../../TransVST_Fixer.exe" "%%d" & cd "/Program Files (x86)\Common Files\Avid\Audio\Plug-Ins")
Please note that I placed the fixer inside the root folder so I just have to copy it once. You have to place it inside your root folder and execute it. What it does:
iterate over each folder
for each one it enters /Contents/x64, executes the fixer (wich is 3 levels above) and after that returns to the original folder.
If you have your plugins in a different folder, you just have to change this part replacing the path for the one you have your plugins in.
cd "/Program Files (x86)\Common Files\Avid\Audio\Plug-Ins"
REMEMBER to place the script on that folder. For this example I place my script on the folder "/Program Files (x86)\Common Files\Avid\Audio\Plug-Ins" and run it (as a .bat).
PS: the fixer will place the fixed plugins in "C:\Users\Public\modified" (just read the screen while executing, it gives you the new files path. If you want to move them to the right path, you can execute this from the new files path ("C:\Users\Public\modified")
for %%d IN (*.aaxplugin) do (mkdir "%%d_temp/Contents\x64" & move "%%d" "%%d_temp/Contents\x64/%%d" & rename "%%d_temp" "%%d")
with that, I iterate over every plugin and create a folder with the same name (I create _temp because of name colision, after moving the file I rename it to the correct one), also with the subfolder "/Contents/x64", and move the plugin inside. Once donde, you can just take the resulting folders and place them in their correct path.
Hope it works, for me it works like a charm.

Batch file giving File Not Found error

Been working on a systematic file search script to retrieve the name of all documents in a directory, and all sub directories that contain a determined search string. Essentially, it will log the search results. It would be nice to have it also search the file names, but that's not yet important.
Code:
#echo off
echo - Will search all files in current directory, and subdirectories.
echo - Will ignore case sensitivity.
echo - Will only search for term within readable documents.
set /p searchfilter=Search Filter:
set results=%CD%\results.txt
echo Searching...
echo Results: > "%results%"
for /f "usebackq tokens=*" %%i in (`dir /s/b/A:-D/o:e`) do (
find /i "%searchfilter%" "%%~nxi" >nul && echo %%~nxi >> "%results%"
)
echo Search complete.
pause
Run-down: System requests a string from the user. Then, the system saves a handle to the results file (thought that would fix the problem, didn't). The system then filters all files, excluding folders, from the directory, and sub directories, printing the bare name of the file (with extension), where it will proceed to scan each file for the search string, and save any positive search results to the text file.
It seems on a number of files, I receive a "File not found - " error, and need help identifying it. My guess, is that it has something to do with trying to find a sub directory file without the directory handle.
find /i "%searchfilter%" "%%i" >nul && echo %%~nxi >> "%results%"
should fix your problem, as you've flagged yourself. If you are searching for a file named fred.txt that exists in a subdirectory but mot in the root of the subtree scanned, then you'll get a File not found error.
Your choice whether you echo just the name and extension to results or whether you echo the full filename, of course. Personally, I'd use `%%i and get the whole thing.
I'd also change
for /f "usebackq tokens=*" %%i in (`dir /s/b/A:-D/o:e`) do (
to
for /f "delims=" %%i in ('dir /s/b/A:-D/o:e') do (
but that's just a matter of style in this case.
This should give you a tool to search filenames in the current folder tree and log the results to a file - in c:\path\file.ext format.
Replace searchstring with your search term and remove *.doc if you want to search all files, or replace it with *.doc *.txt *.ini *.src if you want to filter a number of filetypes.
#echo off
dir /b /s /a-d *.doc |findstr /r /i ".*\\.*searchstring.*" >results.txt

While searching for .pst files FOR keeps looping when it reaches a hidden shortcut folder

The following command creates an infinite loop which is not what I want since I am iterating through files and it needs to end sometime...
Here is what I have:
cd C:\
FOR /R %i IN (*.pst) do #echo %i
See what happens is that when it reaches AppData and finds a .pst (in AppData\Local\Microsoft\Outlook) there is a shortcut folder inside AppData\Local called "Application Data" which loops back to AppData\Local but keeps adding it's name to the address like so:
%AppData%\Local\Application Data\Application Data\Application Data\Microsoft\Outlook\%filename%.pst
What could I add to my code to keep it from looping or much better to completely ignore shortcuts so that the loop ends when it finds all the files that I need?
-----------Edit-------------
This seems to do something similar:
dir /s /b *.pst
You can filter out reparse points with DIR /A-L.
However, using DIR /A-L /S won't work also, because reparse point contents are not reparse points, so, try this:
Instead of FOR use:
FindFiles.bat *.pst c:\
Create a FindFiles.bat file with:
#ECHO OFF
:GetDirFiles %1=Wildcard %2=Path
FOR %%f IN ("%~f2\%~1") DO ECHO %%~ff
FOR /F "DELIMS=" %%d IN ('DIR /B /AD-L "%~f2"') DO CALL :GetDirFiles %1 "%~2\%%d"
This will recursivelly get all directories which are not reparse points and echo items matching pattern for each directory.
Ok, I recommend you use forfiles which should be on your computer if your using windows 7. Type forfiles /? for more info. Try this:
forfiles /p "C:\" /s /m "*.pst" /c "cmd /c (Echo #path)"
That should work perfectly. Im looking in ways of doing this with a for /r loop. It probably involves a dir check in a for /r /d. Tell me if this works fine for you.
Mona

Resources