I have a batch script that goes into a folder's subfolders (excluding one folder) gets .log files, archives them, and then deletes the originals.
Folder structure:
\Logs\logs1
\Logs\logs2
\Logs\logs3
Originally, I had this loop as just one line, which worked and looked like this:
FOR /F "usebackq tokens=* delims=" %%A IN (`DIR "%LogsFilespec%" /B /S ^|find ^"logs3^" /v `) DO %zipCommand% >> %ProcessLog% & DEL "%%~fA" & ECHO Deleting "%%~fA" >> %ProcessLog% & ECHO. >> %ProcessLog%
But, I was instructed to turn it into a simpler-looking FOR DO CALL, and as a result I am stuck, unsure of whats wrong. %targetDate% is YYYYMMDD.
**Edited for fuller code trying rojo's suggestion:
SET ProcessLog=C:\Users\Me\Documents\batch_files\%~n0_%jobLog%.txt
:DetermineArchiveApp
:: Create specifics for ITD Logs collection
SET ITDLogsLocation=C:\Users\Me\Documents\fakeG
SET ITDLogsName=trace*%targetDate%.log
SET ITDLogsFilespec=%ITDLogsLocation%\%ITDLogsName%
:: ********************************************************************************
:: * Check if server has WinZip or 7-Zip installed. setup environment variable *
:: * accordingly with executable path and name, and with any required parameters. *
:: ********************************************************************************
SET PathWinZip="C:\Program Files\WinZip\wzzip.exe"
SET Path7Zip_64bit="C:\Program Files\7-Zip\7z.exe"
SET Path7Zip_32bit="C:\Program Files (x86)\7-Zip\7z.exe"
SET Path7Zip_true="C:\Users\Me\Documents\batch_files\7za.exe"
:: Check for 32-bit version of 7-Zip. If found, configure
:: its command line parameter to produce a .zip file
IF EXIST %Path7Zip_32bit% SET zipCommand=%Path7Zip_32bit% a
::Check for WinZip
IF EXIST %PathWinZip% SET zipCommand=%PathWinZip% -a
:: Check for 64-bit version of 7-Zip. If found, configure
:: its command line parameter to produce a .zip file
IF EXIST %Path7Zip_64bit% SET zipCommand=%Path7Zip_64bit% a
:: Check for 64-bit version of 7-Zip. If found, configure
:: its command line parameter to produce a .zip file
IF EXIST %Path7Zip_true% SET zipCommand=%Path7Zip_true% a
:ArchiveProcess
ECHO ***************************************************** >> %ProcessLog%
::Write the date and time of job starting to a log
ECHO %DATE% %TIME% START >> %ProcessLog%
::Loop through the list that DIR gives for the given folder, and for each folder do zipCommand, excluding ITD\Data\AFS, and write to log
FOR /F "delims=" %%A IN (
'DIR "%LogsFilespec%" /B /S ^|find /v "logs3"'
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%ProcessLog%"
::Write end to log
ECHO %DATE% %TIME% %~nx0 END >> %ProcessLog%
ECHO ***************************************************** >> %ProcessLog%
:DoZip
setlocal
SET "archiveName=%~1"
SET "SourceFileSpec=%~2"
SET "zipCommand=%~3"
SET "RunLog=%~4"
>>"%RunLog%" (
echo Archiving %SourceFileSpec%...
"%zipCommand%" "%archiveName%.zip" "%SourceFileSpec%"
echo %TIME% Deleting %SourceFileSpec%...
DEL "%SourceFileSpec%"
echo;
)
GOTO :EOF
The errors I get from the cmd NOW are:
'""' is not recognized as an internal or external command, operable program or batch file.
Whats wrong with the syntax of either!?
EDIT 2: Heading home now, cant work remotely yet so I'll be back at it tommorow.
The current issue is that: the 7zip command line does not like
"C:\Users\Me\Documents\batch_files\7za.exe" a
and also the >>"%RunLog%" block doesn't work, if comment out just the archival and deletion lines to see what's happening, I just get thrown
The system cannot find the drive specified.
The system cannot find the drive specified.
The system cannot find the drive specified.
The system cannot find the drive specified.
The system cannot find the path specified.
The biggest difference I see is that in your successful one-liner, you have stuff properly quoted; whereas in your call both in the caller and the subroutine, you quote nothing. If any of your paths include spaces or special characters, calamity ensues. Try this:
FOR /F "delims=" %%A IN (
'DIR "%LogsFilespec%" /B /S ^|find /v "logs3"'
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%ProcessLog%"
...
:DoZip <basename> <fqpath> <zipcmd> <log>
setlocal
SET "archiveName=%~1"
SET "SourceFileSpec=%~2"
SET "zipCommand=%~3"
SET "RunLog=%~4"
>>"%RunLog%" (
echo Archiving %SourceFileSpec%...
"%zipCommand%" "%archiveName%.zip" "%SourceFileSpec%"
echo %TIME% Deleting %SourceFileSpec%...
DEL "%SourceFileSpec%"
echo;
)
GOTO :EOF
By the way, did you know you could zip without 3rd party software?
This whole ordeal is turning into a mess. I hope you'll allow me to offer some general scripting advice and receive it as benevolence rather than criticism.
Whenever you set a variable to a string in batch scripting, it helps to set "var=value" with the var=value pair quoted. When you need your variable to be evaluated within quotes, call it as "%var%". This removes any ambiguity about your intentions, and saves you from having to remember which variable values you've quoted and which you haven't.
To directly address your most recent problem, I suggest either adding a 5th argument to your call for "a|-a" (for 7za or wzzip), or determine within the loop whether you should use a or -a based on whether the archiver is 7za or wzzip.
Try this:
#echo off
setlocal
SET "ProcessLog=%USERPROFILE%\Documents\batch_files\%~n0_%jobLog%.txt"
:DetermineArchiveApp
:: Create specifics for ITD Logs collection
SET "ITDLogsLocation=%USERPROFILE%\Documents\fakeG"
SET "ITDLogsName=trace*%targetDate%.log"
SET "ITDLogsFilespec=%ITDLogsLocation%\%ITDLogsName%"
:: ********************************************************************************
:: * Check if server has WinZip or 7-Zip installed. setup environment variable *
:: * accordingly with executable path and name, and with any required parameters. *
:: ********************************************************************************
for %%I in ("%PROGRAMFILES%" "%PROGRAMFILES(x86)%") do (
for %%z in ("%%~I\WinZip\wzzip.exe" "%%~I\7-Zip\7z.exe") do (
if exist "%%~z" set "zipCommand=%%~z"
)
)
if not defined zipCommand set "zipCommand=%USERPROFILE%\Documents\batch_files\7za.exe"
if not exist "%zipCommand%" (
echo Unable to locate 7z.exe, 7za.exe, or wzzip.exe
exit /b 1
)
:ArchiveProcess
::Write the date and time of job starting to a log
>> "%ProcessLog%" (
ECHO *****************************************************
ECHO %DATE% %TIME% START
)
::Loop through the list that DIR gives for the given folder, and for each folder do zipCommand, excluding ITD\Data\AFS, and write to log
FOR /F "delims=" %%A IN (
'DIR "%ITDLogsFilespec%" /B /S ^| find /v "logs3"'
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%ProcessLog%"
::Write end to log
>> "%ProcessLog%" (
ECHO %DATE% %TIME% %~nx0 END
ECHO *****************************************************
)
::End main runtime
goto :EOF
:DoZip
setlocal
SET "archiveName=%~1"
SET "SourceFileSpec=%~2"
SET "zipCommand=%~3"
SET "RunLog=%~4"
if "%zipCommand%"=="%zipCommand:7z=%" (
rem then this is WinZip.
set "switch=-a"
) else set "switch=a"
>>"%RunLog%" (
echo Archiving %SourceFileSpec%...
"%zipCommand%" %switch% "%archiveName%.zip" "%SourceFileSpec%"
echo %TIME% Deleting %SourceFileSpec%...
DEL "%SourceFileSpec%"
echo;
)
GOTO :EOF
Related
UPDATE
I removed the tokens=4 and it started outputting data. It is not skipping past the FOR LOOP. I was skipping too far ahead with the tokens. I am still a little confused as to why it works as a single batch and not from this batch but now at least I know what the issue was. Thank you to everyone that was looking into this for me.
I am writing a script to copy over data from one computer to another. The issue is that it is skipping over the FOR LOOP that I am calling from another FOR LOOP. If you are testing the script it requires two PC's and a mapped T: drive to somewhere on the second computer. I can write the script so it looks for an external drive if that is more helpful to someone.
FOR /F "tokens=4 skip=1" %%a in ('REG QUERY "%_regshell%" /v "%_regdesktop%"') DO (
SET _dt=%%a
echo robocopy "!_dt!" "!_NetworkDrive!\!_fndesktop!" !_params!
echo attrib -h -r "!_NetworkDrive!\!_fndesktop!"
)
If I write the FOR LOOP above in a batch by itself and just echo out %%a then it works without a problem. In this, I can see that it is indeed calling :_backup but it skips directly over the FOR Loop and I am not sure why. I have written scripts like this many times but never had any that just completely ignore the FOR Loop. Can anyone take a look and assist? Thank you.
#echo off
:: Set Variables
SET _driveID=T:
SET _params=/Z /E /COPY:DT /R:1 /W:0 /XD LocalService NetworkService temp "temporary internet files" winsxs Content.IE5 cache /XF ntuser.* *.tmp /XJ /FP /NC /NS /NP /NJH
SET _regshell=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
SET _regdesktop=Desktop
:: Set Current Directory
pushd %SystemDrive%\
:: Start Menu - Create Choices and Options. Send to various places to perform the actions.
:_start
cls
ECHO Please type either option 2 or 3 and then press ENTER on the keyboard?
Echo 2. TRANSFER FILES FROM DESKTOP TO LAPTOP
Echo 3. EXIT THE PROGRAM
echo.
set /p choice=Enter Number:
if '%choice%'=='2' goto _desktopToLaptop
if '%choice%'=='3' goto :EOF
echo "%choice%" is not a valid option. Please try again
echo.
goto _start
:: Detect Drive Letters
:_desktopToLaptop
setlocal EnableDelayedExpansion
FOR /F "usebackq skip=1" %%a IN (`WMIC logicaldisk where DeviceID^="%_driveID%" get caption`) DO (
SET _NetworkDrive=%%a
if exist %%a (
CALL :_backup
goto :EOF
) else (
echo.
echo The laptop does not appear to be attached to the computer.
echo.
pause
goto :EOF
)
)
:_backup
:: Detect the folder locations and begin to backup each location to the laptop.
FOR /F "tokens=4 skip=1" %%a in ('REG QUERY "%_regshell%" /v "%_regdesktop%"') DO (
SET _dt=%%a
echo robocopy "!_dt!" "!_NetworkDrive!\!_fndesktop!" !_params!
echo attrib -h -r "!_NetworkDrive!\!_fndesktop!"
)
echo we are past the for loop
pause
:: Return to directory program was run from
popd
If anyone else runs into this issue or something similar, check your tokens and your skip. Mine worked just fine as a single batch but when I included as a call I had to change the options from tokens=4 skip=1 to tokens=3* skip=2 in order to get the correct output.
The correct tokens in that FOR LOOPS should be:
#echo off
:: Set Variables
SET _driveID=T:
SET _params=/Z /E /COPY:DT /R:1 /W:0 /XD LocalService NetworkService temp "temporary internet files" winsxs Content.IE5 cache /XF ntuser.* *.tmp /XJ /FP /NC /NS /NP /NJH
SET _regshell=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
SET _regdesktop=Desktop
:: Set Current Directory
pushd %SystemDrive%\
:: Start Menu - Create Choices and Options. Send to various places to perform the actions.
:_start
cls
ECHO Please type either option 2 or 3 and then press ENTER on the keyboard?
Echo 2. TRANSFER FILES FROM DESKTOP TO LAPTOP
Echo 3. EXIT THE PROGRAM
echo.
set /p choice=Enter Number:
if '%choice%'=='2' goto _desktopToLaptop
if '%choice%'=='3' goto :EOF
echo "%choice%" is not a valid option. Please try again
echo.
goto _start
:: Detect Drive Letters
:_desktopToLaptop
setlocal EnableDelayedExpansion
FOR /F "usebackq skip=1" %%a IN (`WMIC logicaldisk where DeviceID^="%_driveID%" get caption`) DO (
SET _NetworkDrive=%%a
if exist %%a (
CALL :_backup
goto :EOF
) else (
echo.
echo The laptop does not appear to be attached to the computer.
echo.
pause
goto :EOF
)
)
:_backup
:: Detect the folder locations and begin to backup each location to the laptop.
FOR /F "tokens=3* skip=2" %%a in ('REG QUERY "%_regshell%" /v "%_regdesktop%"') DO (
SET _dt=%%a
echo robocopy "!_dt!" "!_NetworkDrive!\!_fndesktop!" !_params!
echo attrib -h -r "!_NetworkDrive!\!_fndesktop!"
)
echo we are past the for loop
pause
:: Return to directory program was run from
popd
Given that the main issue in your script appears to be the setting of a variable to the data within the defined registry key and value, you could use:
Set "_regshell=HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
Set "_regdesktop=Desktop"
Set "_dt="
For /F "EOL=H Tokens=2*" %%A In ('Reg Query "%_regshell%" /V "%_regdesktop%"'
) Do Set "_dt=%%~B"
If Not Defined _dt GoTo :EOF
Echo "%_dt%"
I want to write a script to prompt user for file path and list all files found. The file path can contain wildcards. Something similar to this. But the batch script version of it. For example:
C:\Somewhere\user*\app\version-*.*\start.exe
The files might be located like this:
C:\Somewhere\user345\app\version-1.0\start.exe
C:\Somewhere\user898\app\version-1.2\start.exe
C:\Somewhere\user898\app\version-1.3\start.exe
I tried to use FOR and it turns out to be so much harder than expected because FOR does not support wildcards in the middle of a path.
Is there a way to list these files? (Maybe without using for?)
I think this recursive solution works pretty well; you may name it WCDIR.bat:
#echo off
setlocal
if "%~1" neq "" set "next=%~1" & goto next
echo Show files selected by several wild-cards
echo/
echo WCDIR wildcardPath
echo/
echo Each folder in the path may contain wild-cards
echo the last part must be a file wild-card
goto :EOF
:next
for /F "tokens=1* delims=\" %%a in ("%next%") do set "this=%%a" & set "next=%%b"
if defined next (
for /D %%a in ("%this::=:\%") do (
setlocal
cd /D "%%~a" 2>NUL
if not errorlevel 1 call :next
endlocal
)
) else (
for /F "delims=" %%a in ('dir /B /A:-D "%this%" 2^>NUL') do echo %%~Fa
)
exit /B
EDIT: I fixed a small bug in the last for /F command.
For example, the output of WCDIR.bat C:\Windows\Sys*\find*.exe command in my Windows 8.1 64-bits computer is:
C:\Windows\System32\find.exe
C:\Windows\System32\findstr.exe
C:\Windows\SysWOW64\find.exe
C:\Windows\SysWOW64\findstr.exe
You can try with the command Where /?
The WHERE command is roughly equivalent to the UNIX 'which' command. By default, the search is done in the current directory and in the PATH.
#echo off
Where /R "%programfiles%" *winrar.exe
pause
#echo off
:: Example d'input
set UserInput=*drive*
:: building the Pattern
set cmd=%Userinput%.exe
:: storage Where.exe command in a macro, the execution will be faster
set whereCmd=where.exe /r c:\windows\ %cmd%
:: execution of macro and output formatting
for /f %%a in ('%whereCmd%') do echo %%~nxa --^> %%a
pause
Right now I've got a batch script that is used to go through a bunch of subfolders, and zip up the logfiles therein, the folder structure is basically like this:
+---fakeG
| +---ExclusionFolder
| | +---LimitlessFolders
| | +---MoreFolders
| | \---SoManyFolders
| +---logs1
| +---logs2
| +---logs3
| +---logs4
| +---logs5
| \---logs6
Each of these subfolders must be traversed, and their subfolders traversed as well. This script has to avoid one specific folder, and it does avoid it, but it uses %| find /v. Although in this example, ExclusionFolder is at the top of the list, in the real folder structure it is not.
Here is how I do it now:
FOR /F "delims=" %%A IN (
'DIR "%LogsFilespec%" /B /S ^| find /v "ExclusionFolder"'
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog%
Inside ExclusionFolder, there are more subfolders, with potentially many more subfolders, so it would slow down the scripts execution having to go into each of them.
SO: Is there a faster way to exclude a folder from a dir call without |find ?
Or do I have to come up with a totally different way to do this?
Edit Sorry, %LogsFileSpec℅ refers to the target file. My original edit was right, and my second edit was wrong.
SET LogsLocation="G:\fakeG\Data\Logs"
SET LogsName="trace*%targetDate%.log"
SET LogsFilespec="%LogsLocation%\%LogsName%"
Sorry for not giving more of the script, I figured the question didn't need much.
Edit2 The process :DoZip works like this:
:DoZip
:: Parameter 1 = Filename without .EXT for Archive Name
:: Parameter 2 = Target file specifics
:: Parameter 3 = Zip Command (Winzip/7zip64/7zip32)
:: Parameter 4 = Zip Parameters (a -tzip, -a)
:: Parameter 5 = ProcessLog
setlocal
SET archiveName=%~1
SET SourceFileSpec=%~2
SET zipCommand=%~3
SET zipParms=%~4
SET RunLog=%~5
ECHO %TIME% Archiving %SourceFileSpec%...
ECHO %TIME% Archiving %SourceFileSpec%... >> %RunLog%
ECHO "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%"
ECHO "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%" >> %RunLog%
"%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%" >> %RunLog%
:: Check errorlevel of executed command
:: If errorlevel != 0, set EC with the errorlevel and echo that there was an error in archival
IF NOT %ERRORLEVEL%==0 (
ECHO ***ERROR archiving %SourceFileSpec% >> %RunLog%
SET EC=%ERRORLEVEL%
ECHO ***ERRORLEVEL RETURNED: %EC% >> %RunLog%
) ELSE (
:: Otherwise, delete the file
ECHO. >> %RunLog%
ECHO. >> %RunLog%
ECHO %TIME% Deleting %SourceFileSpec%...
ECHO %TIME% Deleting %SourceFileSpec%... >> %RunLog%
::Quietly delete the file
DEL /Q %SourceFileSpec%
:: Set ErrorLevel to capture the Delete command result.
SET EC=%ERRORLEVEL%
)
GOTO :EOF
Edit 3 Here is zipCommand
SET PathWinZip=C:\Program Files\WinZip\wzzip.exe
SET Path7Zip_64bit=C:\Program Files\7-Zip\7z.exe
SET Path7Zip_32bit=C:\Program Files (x86)\7-Zip\7z.exe
:: Check for WinZip
IF EXIST "%PathWinZip%" SET zipCommand=%PathWinZip% & SET zipParms=-a
:: Check for 32-bit version of 7-Zip. If found, configure
:: its command line parameter to produce a .zip file
IF EXIST "%Path7Zip_32bit%" SET zipCommand=%Path7Zip_32bit% & SET zipParms=a -tzip
:: Check for 64-bit version of 7-Zip. If found, configure
:: its command line parameter to produce a .zip file
IF EXIST "%Path7Zip_64bit%" SET zipCommand=%Path7Zip_64bit% & SET zipParms=a -tzip
I believe that the following should exclude the subtree in question:
FOR /F "delims=" %%X IN (
'DIR /B /ad ') DO IF /i "%%X" neq "ExclusionFolder" FOR /F "delims=" %%A IN (
'DIR /B /S "%%X\%LogsFilespec%"'
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog%
That is, perform a directory-name scan of the target; if the directory found is not the exclude-name, then do the remainder for that subdirectory.
This approach could be a bit faster:
pushd "%LogsFilespec%"
rem get subfolders of first level only
for /f "tokens=*" %%p in (
'DIR "%LogsFilespec%" /B /AD ^| find /v "ExclusionFolder"'
) do (
rem treat each (here will not be excluded one)
FOR /F "delims=" %%A IN (
'DIR "%%~p" /B /S'
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog%
)
popd
goto :eof
The solution below don't use a single FIND command nor a FOR /F ... one (that requires the execution of a copy of cmd.exe), so I think it should run faster:
#echo off
setlocal
rem Enter to the base folder
cd "%LogsFilespec%"
rem Start the recursive process
call :processThisDir
goto :EOF
:processThisDir
rem Process the files in this folder
for %%A in (*.*) do CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog%
rem Process nested subfolders, but omit "ExclusionFolder"
for /D %%a in (*) do (
if "%%a" neq "ExclusionFolder" (
cd "%%a"
call :processThisDir
cd ..
)
)
exit /B
Hello :) when a friend give you a mp3 file, most often, the title is named that way: "avenged_sevenfold_-_buried_alive.mp3". i want to make a script which permit me to rename every file and folder of current repertoryby replacing "_" by " "(space). this is very long to rename each file manually; my script is here:
#echo off
title Merci qui ?
:debut
echo do you want to rename every files/foldes by replacing "_" by " "? (y/n)
set /p choix=
if %choix%==y (
goto renomage)
if %choix%==n (
goto end)
goto debut
:renomage
set /a x=1 :pointeur de fichier
set /a compteurA=0
set /a compteurB=0
for /f %%a in ('dir /b /a:-d *.*') do set /a compteurA+=1
for /f %%a in ('dir /b /a:d *.*') do set /a compteurB+=1
echo %compteurA% fichiers %compteurB% dossiers
set /a n=compteurA+compteurB
echo number of folder/files batch included %n%
:while1
if %x% GTR %n% goto prochain1
set Strin=???name?ofthe?dossier?number?x?????????????
for /f "tokens=1,* delims=[,]" %%A in ('"%comspec% /u /c echo:%Strin%|more|find /n /v """') do `set /a l=%%A-4`
echo Le nom contient %l% lettres.
:leftspace
set Strin=%Strin:_= %
set str=%Strin:~0,1%
if %str% EQU " "(
set Strin=%Strin:~1,%l%-1%
goto leftspace)
SET /A x +=1
goto while1
:prochain1
echo Success ! (or not)
pause
:end
i just need help for this line:
set Strin=???name?ofthe?dossier?number?x?????????????
otherwise the rest should be ok. if you have some critics or something, go on =)
This solution is reposted from How to Batch Rename Files in Windows: 4 Ways to Rename Multiple Files by Chris Hoffman
PowerShell offers much more flexibility for renaming files in a command-line environment. Using PowerShell, you can pipe the output of one command – known as a “commandlet” in PowerShell terms — to another command, just like you can on Linux and other UNIX-like systems.
First of all, open Powershell ISE and then navigate to the directory (folder) that has the files and folders you'd like to rename by using this command:
cd "C:\your\directory\"
The two important commands you’ll need are Dir, which lists the files in the current directory, and Rename-Item, which renames an item (a file, in this case). Pipe the output of Dir to Rename-Item and you’re in business.
After you launch PowerShell ISE, use the cd command to enter the directory containing your files. You should put the files in their own directory so you don’t accidentally rename other files.
For example, let’s say we don’t want the underscore character in our file names – we’d rather have a space instead.
The following command lists the files in the current directory and pipes the list to Rename-Item. Rename-Item replaces each underscore character with a space.
Dir | Rename-Item –NewName { $_.name –replace "_"," " }
Replace the "_" and "" parts of the command to replace other characters in file names.
Consult Microsoft’s documentation on the Rename-Item commandlet if you want help performing other, more advanced operations.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR %%f IN (ad a-d ) DO FOR /f "delims=" %%a IN (
'dir /b /s /%%f "%sourcedir%\*" '
) DO CALL :chgnam %%a
GOTO :EOF
:chgnam
SET "name=%*"
SET "newname=%name:_= %"
IF "%newname%" neq "%name%" ECHO REN "%name%" "%newname%"
GOTO :eof
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 and directories. Directories are renamed first.
You will need to change sourcedir to point to your required directory. All files and directories in the tree which contain the _ would be renamed - if it's possible to rename them.
[revised and corrected version]
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
PUSHD "%sourcedir%"
FOR %%f IN (ad a-d ) DO FOR /f "delims=" %%a IN (
'dir /b /s /%%f "%sourcedir%\*" '
) DO CALL :chgnam "%%a" "%%~nxa"
POPD
GOTO :EOF
:chgnam
SET "name=%~2"
SET "newname=%name:_-_=-%"
SET "newname=%newname:_= %"
IF "%newname%" neq "%name%" ECHO(REN "%~1" "%newname%"
GOTO :eof
The original version would show incorrect ren syntax (the new-name may not contain a path)
If you want to run on the current directory, simply set the value of sourcedir to a single dot.
I found this script on another site but I can not get it to work and I don't know batch scripting that well
Set objWshShell = WScript.CreateObject("WScript.Shell")
strOSVersion = objWshShell.RegRead("HKLM\Software\Microsoft\Windows NT\CurrentVersion\CurrentVersion")
If strOSVersion = "5.1" Then
Debug.WriteLine("Windows XP")
Rem Insert Windows XP Statements
ElseIf strOSVersion = "6.0" Then
Debug.WriteLine("Windows Vista")
Rem Insert Windows Vista Statements
ElseIf strOSVersion = "6.1" Then
Debug.WriteLine("Windows 7")
Rem Insert Windows 7 Statements
End If
now if I run this I get the error on the second line
'strOSVersion' is not recognized as an internal or external command
operable program or batch file.
= was unexpected at this time.
I do not know why
It's a VB script. You can save in a file named like test.vbs
Then open a command prompt, change directory to where you saved the file. At the prompt type cscript test.vbs.
Before that, I changed the Debug.WriteLine calls to WScript.Echo instead.
This is a Batch Script (.bat) that I've put together and use often for determining OS.
#ECHO OFF
SetLocal
REM --------> EDIT BELOW <--------
REM Edit below if you would like to audit the pc's you run this on and store the information in a file, either T or F (for True or False)
set storeValue=T
REM Edit below the location on a network drive that you can write to
set sharePath=\\servername\sharepath
REM -----> DO NOT EDIT BELOW <-----
IF NOT EXIST C:\Temp MD C:\Temp
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | findstr ProductName>C:\temp\osver.txt
set osver=
set tempLoc=C:\Temp
FOR /F "tokens=3* delims= " %%I IN (%tempLoc%\OSver.txt) DO SET osVer=%%I %%J
echo.-----------------------------------------
echo. You are running: %osVer%
echo.-----------------------------------------
IF '%storeValue%'=='F' goto end
IF '%storeValue%'=='T' goto storeValue
:storeValue
ipconfig |findstr IPv4>c:\temp\ipadd.txt
REM FOR /F "tokens=12* delims=." %%A IN (%tempLoc%\IPAdd.txt) DO SET IPAdd=%%A.%%B
FOR /F "tokens=2* delims=:" %%A IN (%tempLoc%\IPAdd.txt) DO SET IPAdd=%%A
IF EXIST %sharePath%\PC_Audit_List.txt goto audit
echo.PC Audit List>%sharePath%\PC_Audit_List.txt
echo.------------------------------------------------------------->>%sharePath%\PC_Audit_List.txt
goto audit
:audit
echo.%computername% - %IPAdd% - %osVer%>>%sharePath%\PC_Audit_List.txt
goto end
:end
IF EXIST %tempLoc%\OSver.txt del %tempLoc%\OSver.txt /f /q
IF EXIST %tempLoc%\IPAdd.txt del %tempLoc%\IPAdd.txt /f /q
EndLocal
pause
exit
I'm sure this will suit your needs, I've included an option for you to write the IP, Name and then the Version into a file.
#echo off
setlocal EnableDelayedExpansion
::Identify OS
for /F "delims=" %%a in ('ver') do set ver=%%a
set Version=
for %%a in (95=95 98=98 ME=ME NT=NT 2000=2000 5.1.=XP 5.2.=2003 6.0.=Vista 6.1.=7 6.2.=8 6.3=8.1) do (
if "!Version!" equ "this" (
set Version=Windows %%a
) else if "!ver: %%a=!" neq "%ver%" (
set Version=this
)
)
::Identify bit
if exist "%SYSTEMDRIVE%\Program Files (x86)" (
set Type=64 bit
) else (
set Type=32 bit
)
::Display result
echo %Version% %Type%
echo/
pause
Copied from: http://www.dostips.com/forum/viewtopic.php?f=3&t=4387