Storing command results in a variable in batch file - batch-file

I need to search a remote directory (psexec), then store the result in a variable.
I have a directory that is filled with many other folders each containing some files I need to execute. Each computer on the network has the files I need are in different directories.
For example, I would search (using psexec) with
dir *Google_Chrome_49_0_2623_112_X64_EN_R01* /s
And I would get the result
Volume in drive C is OSDISK
Volume Serial Number is C8AD-F658
Directory of C:\Windows\ccmcache\2a
12/04/2016 01:52 PM 458 Google_Chrome_49_0_2623_112_X64_EN_R01.cab
14/04/2016 05:26 PM 69,632 Google_Chrome_49_0_2623_112_X64_EN_R01.mst
2 File(s) 70,090 bytes
Total Files Listed:
2 File(s) 70,090 bytes
0 Dir(s) 4,726,218,752 bytes free
Now I need the same batch file to cd into the directory 2a and execute a script inside.
Is there any way to store '2a' in a variable so I can cd into it?
Currently I am doing this in 2 steps, where the batch will show me the search results, then prompt for the directory:
psexec \\%PCNAME% cmd /c (cd ..\ccmcache ^& dir *Google_Chrome_49_0_2623_112_X64_EN_R01* /s)
SET DIRECTORY=%1
SET /P DIRECTORY=Enter Directory:
Problem is, I need this to be fully automated. How can I do this?
Note: I've looked at several other threads, and none of the answers seem to help me. Seemingly the results from psexec don't flow back to the local interface.
I've tried:
for /f %%a in (psexec \\%PCNAME% cmd /c (cd ..\ccmcache ^& dir *Google_Chrome_49_0_2623_112* /s ^| FIND "Directory of C:\Windows\ccmcache\") DO (
SET v=%%a
)
to try to set the entire result line to a var, but when I check the var, it's empty.

I just discovered that you can map to a network share with pushd and run the search there instead of dealing with psexec until you need it.
So my code now looks like:
pushd \\%PCNAME%\C$\Windows\ccmcache
for /f "tokens=3" %%a in ('dir *Google_Chrome_49_0_2623_112* /s ^| FIND "Directory"') DO (
set v=%%a
for /f "tokens=4 delims=\" %%m in ('echo !v!') do (set x=%%m)
)
popd
Where %x% is now the directory I'm searching for.

Related

How to copy all files with .jpg extension to a new folder?

I am trying to find all the pictures on my computer and copy them all to just 1 folder. Here is the command I am using in Admin level Command Prompt.
C:>dir /s /b *.jpg | findstr /v .jpg > AllPics
For some reason I get this output: "Access is denied."
What can I do to fix this?
List the full path names of the JPG files in the current directory and all subdirectories:
dir /s /b *.jpg
Redirect the standard output stream of the dir command to the standard input stream of the findstr command. Exclude any file that contains .jpg (case sensitive) in the full path name:
| findstr /v .jpg
The result of the previous action seems to be counter-intuitive as it will negate a lot of output generated by the dir command.
Write the standard output stream of the findstr command to a file called AllPics (without a file extension) in the current directory:
> AllPics
The current directory seems to be set to the root of the C: drive. Because administrator privileges are required to save files directly to the root of the C: drive, you'll receive the "Access is denied" error message.
As pointed out by TripeHound, the "Access is denied" error might be caused because there already exists a folder named AllPics on the root of the C: drive.
One way to get the desired result is to parse each JPG file to the xcopy command:
setlocal
set "files=c:\*.jpg"
set "destDir=c:\AllPics"
for /f "delims=" %%f in ('dir "%files%" /b /s') do (
xcopy "%%f" "%destDir%\"
)
I've added another variant of the script that alters the destination name of the file to be copied which prevents potentially overwriting any possible duplicates.
setlocal enabledelayedexpansion
set "files=c:\*.jpg"
set "destDir=c:\AllPics"
for /f "delims=" %%f in ('dir "%files%" /b /s') do (
for %%d in ("%destDir%\%%~nf*") do (
set /a count+=1
)
xcopy "%%f" "%destDir%\%%~nf!count!%%~xf*"
set count=
)
Due to delayed expansion, the last variant of the script is unable to handle files that contain carets (^) within their fully qualified path name.
When a command-line contains environment variables that are expanded at execution time (like the count variable in this script), the entire command-line seems to be parsed twice. The for-loop variables (%%f and variants thereof) will be expanded during the first parse, the count variable is expanded during the second parse. Because the for-loop variables are already expanded when the second parse takes place, any singular carets present in the values of the for-loop variables are swallowed by the parser and omitted from the final result.
Here is the revision of the script that should take care of the problem described:
setlocal enabledelayedexpansion
set "type=.jpg"
set "source=c:\"
set "dest=c:\AllPics"
for /r "%source%" %%f in ("*%type%") do (
for %%d in ("%dest%\%%~nf*") do (
set /a count+=1
)
set "source=%%f"
set "dest=%dest%\%%~nf"
xcopy "!source!" "!dest!!count!%type%*"
set count=
)
I do this with WinRAR. Archive files from different folders with recursive scan, then extract in one folder (with e option, not x which restores the directory tree).

Batch file: compare files?

I have a batch file for checking files in a map.
My situation:
I have for example Map A on Directory A.
On Directory B I have also Map A. But on Directory B are people working in those files, so there is a change that files can be delete or missing.
Now I want compare those 2 maps for missing files, that maybe delete or is missing.
So comparing must be like this:
Directory A with Map A :compare-> Directory B with Map A
Result must be: No changes or missing files!
Can you help me?
Thanks!!
Assuming you have correctly shared the remote directory on your network, and have configured the relevant NetBIOS, TCP/IP settings, and are on the same Subnet Mask etc. Then something like this should work:
#echo off
net use x: "\\COMPUTER-NAME\PATH-TO-SHARED-SUBDIRECTORY"
del /q "missing.txt" 2>nul
for /f "tokens=*" %%i in ('dir /b /a:-d-h x:') do (
if not exist "%userprofile%\DIRECTORY-PATH\%%i" echo %%i
)>>missing.txt
pause
I may have it the wrong way around, otherwise it would be:
#echo off
net use x: "\\COMPUTER-NAME\PATH-TO-SHARED-SUBDIRECTORY"
del /q "missing.txt" 2>nul
for /f "tokens=*" %%i in ('dir /b /a:-d-h "%userprofile%\SUBDIRECTORY-PATH\"') do (
if not exist "x:\%%i" echo %%i
)>>missing.txt
pause
Either way the command you'd be interested in, among others, is net use
xcopy /L /d "directory a\*" "directory b\*"
will show the files that are in directory A but missing or changed in directory B.

CMD deleting folder recursively (i.e. same folder name in multiple locations)

Due to a Dreamweaver setting mess-up, we've had thousands of "_notes" folders pop up in our websites dev & qa areas. There's too many to delete through Windows Explorer - everything just locks up - so I was hoping to run a batch script to sort it out for us once and for all. The problem is I'm not entirely sure that "rd /S" will do what I want.
My understanding is that rd /S will look recursively in the folder I tell it, so if I say:
rd /S r:/<siteName>/_notes/
then it will just look in the _notes folder and delete what's in there and then try to move further down that tree. What I need is a script that would take into account things like the following:
r:/<siteName>/_notes/
r:/<siteName/<someFolder>/_notes/
r:/<siteName/<someOtherFolder>/_notes/
r:/<siteName/<someFolder>/<someSubFolder>/_notes/
r:/<siteName/<someFolder>/<iThinkIveMadeMyPoint>/_notes/
Hope I made sense...
I found this in another thread, but it doesn't work with folders with a . in the name, so it's no use for site names...
#Echo OFF
REM Important that Delayed Expansion is Enabled
setlocal enabledelayedexpansion
REM This sets what folder the batch is looking for and the root in which it starts the search:
set /p foldername=Please enter the foldername you want to delete:
set /p root=Please enter the root directory (ex: C:\TestFolder)
REM Checks each directory in the given root
FOR /R %root% %%A IN (.) DO (
if '%%A'=='' goto end
REM Correctly parses info for executing the loop and RM functions
set dir="%%A"
set dir=!dir:.=!
set directory=%%A
set directory=!directory::=!
set directory=!directory:\=;!
REM Checks each directory
for /f "tokens=* delims=;" %%P in ("!directory!") do call :loop %%P)
REM After each directory is checked the batch will allow you to see folders deleted.
:end
pause
endlocal
exit
REM This loop checks each folder inside the directory for the specified folder name. This allows you to check multiple nested directories.
:loop
if '%1'=='' goto endloop
if '%1'=='%foldername%' (
rd /S /Q !dir!
echo !dir! was deleted.
)
SHIFT
goto :loop
:endloop
read HELP FOR, HELP SET and HELP IF
note that FOR /D /R will recursively walk the directory tree.
note also that %~na is the funny syntax to extract the name part of a full path.
so, putting this little pieces togethere, try this command on the command line
for /d /r %a in (*) do #if %~na==_notes #echo rd %a
after careful testing, remove the echo command.
This command has worked for me and I hope this could help. Switch to the common root folder, and type in CMD:
for /d /r . %d in (<folder name>) do #if exist "%d" rd /s/q "%d"
Change the to the name of folder you want to remove. Then all children folders with this name would be removed.

Windows FOR command not expanding system environment variables

I have been using this site for sometime and have found it quite valuable in finding solutions to scripting issues. Today I resolve to ask a question as I have not found my solution after exhausting 3 days here, on Superuser, and Googling. So much for all about me, now my point...
I have several installs of a program, each slightly different version or flavor. Each install has a text file defining variables for its use. One of these variables defines a folder for user specific settings, USERSET=%APPDATA%\foo1\foo2. Overtime these user settings can become corrupt. I want to be able to delete these folders with a batch file or script. In short, I want to search a directory for text files that contain a specific string which sets a variable that points to a folder, get the value of that variable and use it to remove a directory.
This is what I have so far:
for /f "tokens=2 delims==" %%G in ('dir /b /s c:\foo\*.txt ^| findstr /i /f:/ userset') do rd /s /q %%G
The output looks like this:
H:\>rd /s /q %appdata%\foo1\foo2\USERSET
The system cannot find the file specified.
Apparently %appdata% does not expand?
Of course if I just type rd /s /q %appdata%\foo1\foo2\USERSET at the command prompt, it works.
I'm open to other languages, I am mostly familiar with Windows command line.
This is because environment variable expansion is done at parse time of a statement. While your for loop is running and %%G actually gets a value it's too late; variables have already been expanded.
You can work around this with a subroutine, I guess:
pushd C:\foo
for /f ... %%G in (...) do call :process "%%G"
popd
goto :eof
:process
call set "X=%~1"
rd /s /q "%X%"
goto :eof
I'd simply insert a CALL before the RD
....CALL RD ...
although I'd also try
....CALL ECHO(RD ...
first to verify - just for safety's sake.

Batch File to Loop Through Each File in Directory and Count Records in Each File

I am trying to create a "Checking" batch file for an FTP process to ensure no data is lost via the FTP transmission.
The batch file needs to look at every single file inside a directory and and count the number of records. The result will be delimited by ~ (i.e. Output1~200). So far I've gotten this:
type "">Check.txt
set file=Output1.txt
set /a cnt=0
for /f %%a in ('type "%file%"^|find "" /v /c') do set /a cnt=%%a
echo %file%~%cnt% >> Check.txt
pause
The first type "">Check.txt is to clear the file then it looks for a specific file. How do I set this to loop therough all the file names within the directory dynamically?
This uses your code and processes every file in the directory - and counts the number of lines. Is that what you wanted to do?
#echo off
(
for %%a in (*.*) do (
for /f %%b in (' find "" /v /c ^< "%%a" ') do echo %%a~%%b
)
)> "%userprofile%\desktop\Check.txt"
Batch file links and help
For built in help on commands & syntax, type this in a cmd window
For W2K: HH windows.chm::ntcmds.htm
For XP: HH ntcmds.chm
Some batch related forums and material
http://www.dostips.com/forum/
http://www.ss64.com/nt/index.html
http://www.robvanderwoude.com/
http://www.computerhope.com/forum/
http://stackoverflow.com
http://forums.techguy.org/23-dos-other/
http://www.netikka.net/tsneti/info/tscmd.php <--- tscmd.zip has many samples
Search these Usenet groups. Replace "your+keywords" with your keywords
alt.msdos.batch
alt.msdos.batch.nt
http://groups.google.com/groups?group=alt.msdos.batch&q=your+keywords
http://groups.google.com/groups?group=alt.msdos.batch.nt&q=your+keywords

Resources