How can I set Path by browsing popup? - batch-file

I have below script, in this there are two path one is Target path (only one) and another source path (variables).
About below script function: I'll run this once in a month and it'll go the souce path (10 path) and copy lates file then copy&rename to target path (common for all the files).
note : file which is copyed form the respacted source should be rename as per script like:
file from "F:\Financial\Data\Reports\AccruntPnLMTD" should be rename as "PNL.csv"
#echo off
setlocal
set DateFolder=04.2013
set TargetFolder=F:\Financial\Data\%DateFolder%\Final Reports
:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "F:\Financial\Data\Reports\AccruntPnLMTD" "%TargetFolder%\PNL.csv"
:: copy the newest file from AccountPnlMTD and rename it to AC.csv
call :copyAndRename "F:\Financial\Data\Reports\AccountPnlMTD" "%TargetFolder%\AC.csv"
:: copy the newest file from ExpensesMTD and rename it to EXPMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\ExpensesMTD" "%TargetFolder%\EXPMTD.csv"
:: copy the newest file from ExpensesYTD and rename it to EXPYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\ExpensesYTD" "%TargetFolder%\EXPYTD.csv"
:: copy the newest file from AccrualPnLYTD and rename it to PNLYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\AccrualPnLYTD" "%TargetFolder%\PNLYTD.csv"
:: copy the newest file from AccountYTD and rename it to ACYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\AccountYTD" "%TargetFolder%\ACYTD.csv"
:: copy the newest file from BalanceMTD and rename it to BSMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\BalanceMTD" "%TargetFolder%\BSMTD.csv"
:: copy the newest file from BalanceYTD and rename it to BSYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\BalanceYTD" "%TargetFolder%\BSYTD.csv"
:: copy the newest file from FinancialStmtMTD and rename it to FSMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\FinancialStmtMTD" "%TargetFolder%\FSMTD.csv"
:: copy the newest file from FinancialStmtYTD and rename it to FSYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\FinancialStmtYTD" "%TargetFolder%\FSYTD.csv"
:: Done
goto :eof
:copyAndRename
set SourceFolder=%~1
set TargetFile=%~2
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set "NewestFile=%%F"
:: copy and rename it to the target
copy "%SourceFolder%\%NewestFile%" "%TargetFile%"
:: Done with this subroutine
goto :eof
I want's to give both path after run the script (popup should ask for the path)

Excuse me. Your question is not clear. I assume that you want to copy and rename the 10 given files but not with the fixed paths given in the program, but with variable paths given when the program run. If this is correct, the program must get first the Target path (only one) and then the source path for each one of the files.
The Batch file below is a preliminary version that achieve previous process. If this solution is what you want, then the "browsing popup" part for the paths may be added instead of the simple "set /P folder=Enter folder:" commands. Or perhaps this version is enough for you?
EDIT: I modified the solution below in order to include these new requests:
I have variable target path for diffrent clients like for client a
path wil be F:\Financial\ClientA\Data\%DateFolder%\Final Reports..&
for client B "F:\Financial\ClientB\Data\%DateFolder%\Final Reports"
same goes in source path like Client A path
"F:\Financial\Data\Reports\Client A\AccruntPnLMTD ; for client B Path
will be F:\Financial\Data\Reports\Client B\AccruntPnLMTD..file folder
names (AccruntPnLMTD,AccruntPnLMTD..etc) will reman same for each
clients
LAST EDIT: The Batch file below has been modified for the last time in accordance with the last paragraph in this answer: Browse the existent folders in the disk and pick one.
#if (#CodeSection == #Batch) #then
#echo off
setlocal
rem Activate the browsing pop-up and ask for TargetFolder
for /F "delims=" %%a in ('CScript //nologo //E:JScript "%~F0" "Select the Target folder"') do (
set TargetFolder=%%a
)
rem Activate the browsing pop-up and ask for SourceFolder
for /F "delims=" %%a in ('CScript //nologo //E:JScript "%~F0" "Select the Source folder"') do (
set ClientSourceFolder=%%a
)
rem Process the list of "sourceFolder=fileName" pairs
for %%a in ("AccruntPnLMTD=PNL" "AccountPnlMTD=AC" "ExpensesMTD=EXPMTD" "ExpensesYTD=EXPYTD" "AccrualPnLYTD=PNLYTD"
"AccountYTD=ACYTD" "BalanceMTD=BSMTD" "BalanceYTD=BSYTD" "FinancialStmtMTD=FSMTD" "FinancialStmtYTD=FSYTD"
) do (
rem copy the newest file from sourceFolder and rename it to fileName.csv
for /F "tokens=1,2 delims==" %%b in (%%a) do (
call :copyAndRename "%%b" "%%c"
)
)
:: Done
goto :eof
:copyAndRename
set SourceFolder=%ClientSourceFolder%\%~1
set TargetFile=%TargetFolder%\%~2.csv
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set
"NewestFile=%%F"
:: copy and rename it to the target
copy "%SourceFolder%\%NewestFile%" "%TargetFile%"
:: Done with this subroutine
goto :eof
#end
// JScript section
// Creates a dialog box that enables the user to select a folder.
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774065(v=vs.85).aspx
var shl = new ActiveXObject("Shell.Application");
var folder = shl.BrowseForFolder(0, WScript.Arguments(0), 0, 0);
WScript.Stdout.WriteLine(folder ? folder.self.path : "");
In this new solution you may SELECT the desired client via the parameter of the Batch file. For example, if the Batch file is called example.bat, use this command for ClientA:
example.bat ClientA
You must note that BROWSING FOR A FOLDER is an interactive operation that present a pop-up window with all existent folders and allows you to choose one of them.
EDIT: Some explanations added
It seems that there is a confusion here. In your question you show as examples of target and source folders these ones:
set TargetFolder=F:\Financial\Data\%DateFolder%\Final Reports
:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "F:\Financial\Data\Reports\AccruntPnLMTD"
However, in posterior comments you said:
I have variable target path for diffrent clients like for client a path wil be
F:\Financial\ClientA\Data\%DateFolder%\Final Reports..& for client B
F:\Financial\ClientB\Data\%DateFolder%\Final Reports
same goes in source path like Client A path
F:\Financial\Data\Reports\Client A\AccruntPnLMTD ; for client B Path will be
F:\Financial\Data\Reports\Client B\AccruntPnLMTD..
file folder names (AccruntPnLMTD,AccruntPnLMTD..etc) will reman same for each clients
You must realize that two previous forms are entirely different: in the first one the folder path is constant, but in the second one the folder path must be changed for each client. A Batch file solution is always designed with fixed requirements. This point is not clear in your answer nor in your comments, so I assumed certain details in order to write a Batch solution. I think there are two ways to solve this problem, depending of what the problem is:
1- Select the appropriate folders for each client: in this case I assumed that path folders have this form:
Target Folder is formed by "F:\Financial\" followed by a variable part that select each client, followed by "\Data\%DateFolder%\Final Reports".
Source path is formed by "F:\Financial\Data\Reports\" followed by a variable part that select each client, followed by each one of the 10 different folders (AccruntPnLMTD,AccruntPnLMTD..etc).
If this is the problem, then my solution above solve it. You just need to place the desired folder name as parameter of the Batch file. For example, if the name of the folder for client a is "ClientA", execute this command:
nameOfTheBatchFile ClientA
If the name of the folder for client B is "ClientB", execute this command:
nameOfTheBatchFile ClientB
If the name of the folder have spaces, enclose it in quotes; for example, for "Any other client" execute this command:
nameOfTheBatchFile "Any other client"
However, your posterior comments and insistence on using terms like "browsing popup", "asking for the path", etc. makes me think that the previously explained problem is not the one you want to solve. There is another possibility:
2- Browse the existent folders in the disk and pick one: in this case when the program run it present a "browsing popup" window that give access to all folders in the disk and allows you to select anyone of them. Note that the browsing window can NOT restrict the browse for any particular name format; if you want that the selected folder have certain characteristics, like the data placed after "Data\" part be today's date in "MM.YYYY" format or any other restriction, this checking must be done after the user choose a folder, so the program will indicate that the selected folder was invalid and popup the browsing window again.
I encourage you to clearly explain your requirements. Please, modify your original question so anyone can understand the problem after read it and don't require to review all the comments in all answers.

This is untested - it merges your code with the popup routine and asks for the source folder once, where all the folders are expected to be.
#echo off
setlocal
set DateFolder=04.2013
:: set the source and target folders
call :getpath
set "TargetFolder=%TargetFolder%\%DateFolder%\Final Reports"
:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "AccruntPnLMTD" "%TargetFolder%\PNL.csv"
:: copy the newest file from AccountPnlMTD and rename it to AC.csv
call :copyAndRename "AccountPnlMTD" "%TargetFolder%\AC.csv"
:: copy the newest file from ExpensesMTD and rename it to EXPMTD.csv
call :copyAndRename "ExpensesMTD" "%TargetFolder%\EXPMTD.csv"
:: copy the newest file from ExpensesYTD and rename it to EXPYTD.csv
call :copyAndRename "ExpensesYTD" "%TargetFolder%\EXPYTD.csv"
:: copy the newest file from AccrualPnLYTD and rename it to PNLYTD.csv
call :copyAndRename "AccrualPnLYTD" "%TargetFolder%\PNLYTD.csv"
:: copy the newest file from AccountYTD and rename it to ACYTD.csv
call :copyAndRename "AccountYTD" "%TargetFolder%\ACYTD.csv"
:: copy the newest file from BalanceMTD and rename it to BSMTD.csv
call :copyAndRename "BalanceMTD" "%TargetFolder%\BSMTD.csv"
:: copy the newest file from BalanceYTD and rename it to BSYTD.csv
call :copyAndRename "BalanceYTD" "%TargetFolder%\BSYTD.csv"
:: copy the newest file from FinancialStmtMTD and rename it to FSMTD.csv
call :copyAndRename "FinancialStmtMTD" "%TargetFolder%\FSMTD.csv"
:: copy the newest file from FinancialStmtYTD and rename it to FSYTD.csv
call :copyAndRename "FinancialStmtYTD" "%TargetFolder%\FSYTD.csv"
:: Done
goto :eof
:copyAndRename
set "FileFolder=%SourceFolder%\%~1"
set "TargetFile=%~2"
echo copying "%FileFolder%"
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%FileFolder%"') do set "NewestFile=%%F"
:: copy and rename it to the target
copy "%FileFolder%\%NewestFile%" "%TargetFile%" >nul
:: Done with this subroutine
goto :eof
:getsourcepath
Call :BrowseFolder "Choose Source folder" "C:\Program Files\"
Set "SourceFolder=%Result%"
Call :BrowseFolder "Choose Target folder" "C:\Users\"
Set TargetFolder=%Result%
REM echo %SourceFolder%
REM echo %TargetFolder%
:: Done
goto :eof
:BrowseFolder
set Result=
set input="%~1" & set default="%~2"
:: Temporary files
set vbs=%temp%\_.vbs
set tmp=%temp%\_.cmd
:: Build VBScript file
findstr "'%skip%VBS" "%~f0" > "%vbs%"
:: Run the script with WSH and set Path as Env variable %Result%
for /f "delims=" %%a in ('cscript /nologo "%vbs%" ') do set "Result=%%a"
DEL %VBS%
set vbs= & set tmp= & set input= & set default=
goto :EOF
set WshShell=WScript.CreateObject("WScript.Shell") 'VBS
set shell=WScript.CreateObject("Shell.Application") 'VBS
sInput=WshShell.ExpandEnvironmentStrings("%input%") 'VBS
sDefault=WshShell.ExpandEnvironmentStrings("%default%") 'VBS
sInput = Replace(sInput, chr(34), "") 'VBS
sDefault = replace(sDefault,chr(34),"") 'VBS
set folder=shell.BrowseForFolder(0,sInput,0,sDefault) 'VBS
if typename(folder)="Nothing" Then 'VBS
wscript.echo "set Result=Dialog Cancelled" 'VBS
WScript.Quit(1) 'VBS
end if 'VBS
set folderItems=folder.Items() 'VBS
set folderItem=folderItems.Item() 'VBS
pathname=folderItem.Path 'VBS
wscript.echo pathname 'VBS

Related

Batch copy multiple files from different folders with their paths listed in a txt file, and rename any duplicates

I've been trying to tackle this problem for few days now to no avail. I have no programming experience whatsoever and this task has been driving me nuts.
I have a txt file that has a list of paths to files that need to be copied. Some 8000 paths are in this file.
Copying each item isn't such a big deal as I can just add the copy command and destination before/after each path.
The crux of my issue is that many of these files have the same filename and when they're in different directories it's not a problem.
However I need all the files in the same destination folder and it keeps overwriting itself.
To sum up, I have a .txt file that basically looks like this:
D:\Big folder\Folder\Subfolder a\filea.file
D:\Big folder\Folder3\Subfolder za\filek.file
D:\Big folder\Folder\Subfolder ds\filed.file
D:\Big folder8\Folder\Subfolder p\filea.file...
I need some tool that will let me copy all of these files into one destination folder, and make sure any duplicates get renamed so that they aren't overwritten.
such that filea.file and filea.file become filea.file and filea1.file
EDIT: so far I've come up with
FOR /F "tokens=* usebackq" %i IN (`type "C:\Users\username\Desktop\completelist.txt"`) DO COPY "%i" "E:\destination\"
which does the read and copy job but not the rename part
Save script below to Copy.bat, open Cmd Prompt from the script directory, and run the bat. It works well for me. Post exact errors, if any.
#echo off
setlocal enabledelayedexpansion
set file=%userprofile%\Desktop\completelist.txt
set "dest=E:\destination" & set "i=" & pushd !dest!
for /f "usebackq tokens=*" %%G in ("%file%") do (
call :rename %%~nG %%~xG %%G
copy "%%G" "%dest%\!target!" >nul )
popd
exit /b
:rename
set "target=%1!i!%2"
:loop
set /a i+=1
if exist "!target!" set "target=%1!i!%2" & goto :loop
set "i=" & echo Copied %3 to !target!
exit /b

How to use batch job to add the file "create date" into all the files in a directory?

I have a folder that gets a new file added everyday to the folder with the same file name but incremental extension such as .001, .002, .003, etc. However, if there's no file within the folder it starts at .001 again.
The problem is they are all named the same and if I move them to another folder to archive them it would just overwrite the same file over and over again. I could create a folder each day with the date with only one file in it, but that seems a bit redundant.
Is there a way to look at the create date of each file and rename it to the create date?
I've gotten this far, but it looks like for this situation I have to use a static file name, how to loop through the entire directory?
SET filename = C:\test.001
FOR %%f IN (%filename%) DO SET filedatetime=%%~tf
rename c:\test.001 C:\test_%filedatetime%.txt
move C:\*.txt C:\archive\
this provides the correct sort order:
#echo off &setlocal disableDelayedExpansion
set "startfolder=%userprofile%\test"
cd /d "%startfolder%"
for %%a in (*) do (
for /f "delims=." %%b in ('wmic datafile where "name='%startfolder:\=\\%\\%%~a'" get lastmodified^|find "."') do (
echo(ren "%startfolder%\%%~a" "%%~b.txt"
)
)
Remove echo to get it working.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "targetdir=c:\sourcedir"
SET "destdir=c:\destdir"
PUSHD "%targetdir%"
FOR %%a IN (*.*) DO (
SET "timestamp=%%~ta"
SET "timestamp=!timestamp:/=_!
SET "timestamp=!timestamp::=_!
SET "timestamp=!timestamp:.=_!
SET "timestamp=!timestamp:,=_!
SET "timestamp=!timestamp: =_!
ECHO MOVE "%%a" "%destdir%\%%~na.!timestamp!"
)
GOTO :EOF
This should work with any file in the nominated target directory where the name does not include ! or ^.
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
The gymnastics around timestamp are intende to replace /: with _ since these are illegal filename characters. Space., are similarly replaced - they're legal but often painful.
If you want the destination filename to be name.003.timestamp, remove the ~na from the destination name.
Try like this :
SET $path=The_path_who_contain_the_FILES
FOR /F "DELIMS=" %%f IN ('dir "%$path%" /a-d/b') DO (
SET filedatetime=%%~tf
move "%%~dpnxf" "C:\archive\test_%filedatetime%.txt")

FTP Delete local files if they no longer exist on remote server

I is it possible using the script below to delete the local files if they no longer exist on the remote directory? Currently this downloads all new files but wont delete files that no longer exist on the ftp server?
#Echo Off
REM -- Define File Filter, i.e. files with extension .txt
set FindStrArgs=/x "..*\...*"
REM -- Extract Ftp Script to create List of Files
Set "FtpCommand=ls"
Call:extractFileSection "[Ftp Script 1]" "-">"%temp%\%~n0.ftp"
Rem Notepad "%temp%\%~n0.ftp"
REM -- Execute Ftp Script, collect File Names
Set "FileList="
For /F "Delims=" %%A In ('"Ftp -v -i -s:"%temp%\%~n0.ftp"|Findstr %FindStrArgs%"') Do (
Call Set "FileList=%%FileList%% "%%A""
)
REM -- Extract Ftp Script to download files that don't exist in local folder
Set "FtpCommand=mget"
For %%A In (%FileList%) Do If Not Exist "%%~A" Call Set "FtpCommand=%%FtpCommand%% "%%~A""
Call:extractFileSection "[Ftp Script 1]" "-">"%temp%\%~n0.ftp"
Rem Notepad "%temp%\%~n0.ftp"
For %%A In (%FtpCommand%) Do Echo.%%A
REM -- Execute Ftp Script, download files
ftp -i -s:"%temp%\%~n0.ftp"
Del "%temp%\%~n0.ftp"
GOTO:EOF
:extractFileSection StartMark EndMark FileName -- extract a section of file that is defined by a start and end mark
:: -- [IN] StartMark - start mark, use '...:S' mark to allow variable substitution
:: -- [IN,OPT] EndMark - optional end mark, default is first empty line
:: -- [IN,OPT] FileName - optional source file, default is THIS file
:$created 20080219 :$changed 20100205 :$categories ReadFile
:$source http://www.dostips.com
SETLOCAL Disabledelayedexpansion
set "bmk=%~1"
set "emk=%~2"
set "src=%~3"
set "bExtr="
set "bSubs="
if "%src%"=="" set src=%~f0& rem if no source file then assume THIS file
for /f "tokens=1,* delims=]" %%A in ('find /n /v "" "%src%"') do (
if /i "%%B"=="%emk%" set "bExtr="&set "bSubs="
if defined bExtr if defined bSubs (call echo.%%B) ELSE (echo.%%B)
if /i "%%B"=="%bmk%" set "bExtr=Y"
if /i "%%B"=="%bmk%:S" set "bExtr=Y"&set "bSubs=Y"
)
EXIT /b
If possible, use an ftp client like lftp. It will give you options to mirror two ftp locations in one line of code (see mirror option). Also check out the flags:
--only-newer
--parallel=10
--delete

Renamig files which have date and extension number can be variable

Ok let me explaned it again
I have two location :
F:\Reporting\02.2013 in the folder "02.2013" I have below files
Balance Sheet_20130228_045485.xls 3/22/2013 2:40 PM
Balance Sheet_20130228_024867.xls 3/23/2013 1:40 PM
Balance Sheet_20130228_023556.xls 3/23/2013 3:50 PM
F:\Statements\02.2013 in the folder "02.2013" I have below files
FS_20130228_045485.xls 3/22/2013 4:40 PM
FS_20130228_024867.xls 3/23/2013 1:40 PM
FS_20130228_023556.xls 3/23/2013 6:45 PM
First I wants to moov the latest modified files from both the folder to Target folder :
Target folder is F:\accounting\02.2013
Then I wants to rename those files as
Balance Sheet_20130228_023556.doc as BalanceMTD.xls
FS_20130228_045485.doc as FS.xls
note: I have to do this activity every month,
so folder location will be change like F:\Reporting\03.2013
and file name also will be change like FS_20130331_045465.doc 4/27/2013 4:30 PM
Can you please suggest me any batch file which can help me to do this.
I'll change the date every month if required before execute it.
This will move and rename the newest file from each of your source directories:
#echo off
setlocal
set DateFolder=02.2013
set TargetFolder=F:\Accounting\%DateFolder%
:: Move the newest file from Reporting and rename it to BalanceMTD.xls
call :MoveAndRename "F:\Accounting\%DateFolder%" "%TargetFolder%\BalanceMTD.xls"
:: Move the newest file from Statements and rename it to FS.xls
call :MoveAndRename "F:\Statements\%DateFolder%" "%TargetFolder%\FS.xls"
:: Done
goto :eof
:MoveAndRename
set SourceFolder=%~1
set TargetFile=%~2
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set "NewestFile=%%F"
:: Move and rename it to the target
move "%SourceFolder%\%NewestFile%" "%TargetFile%"
:: Done with this subroutine
goto :eof
I've put the bulk of the working code in a "subroutine" named MoveAndRename, which simply finds the newest file in a particular folder (using a for /f loop over a dir /a-d to loop over all files in order of date, remembering only the last one), then a move to move and rename it to the target. (If you want to keep the original file, then do copy instead.)
The top part of the batch file then just calls the MoveAndRename subroutine multiple times, once for each source folder you want to look at.
If you want to avoid editing the batch file every month, change the third line to this:
set DateFolder=%1
and pass the date to the batch file as an argument: MonthlyProcess.bat 02.2013. Or you can set DateFolder using the %date% environment variable, but since it is formatted based on your locale settings, and it is well documented elsewhere, I will leave that as an exercise for you.
#echo off
setlocal EnableDelayedExpansion
cd F:\MY DOCUMENTS\zyx
rem Process all file names
for /F "delims=" %%a in ('dir /B *.xls') do (
rem Get base name before first underscore (ie: "Balance Sheet" or "FS")
for /F "delims=_" %%b in ("%%a") do (
rem Check if name have two words (ie: "Balance"/"Sheet" or "IC"/"Activities")
for /F "tokens=1,2" %%c in ("%%b") do (
rem If base name have just one word...
if "%%d" equ "" (
rem New name is that word (ie: "FS")
set newName=%%c
) else (
rem We don't know what goes here!
)
)
)
ren "%%a" "!newName!.xls"
)
We could complete previous program if you give us details on how to do so...

Iterating through folders and files in batch file?

Here's my situation. A project has as objective to migrate some attachments to another system.
These attachments will be located to a parent folder, let's say "Folder 0" (see this question's diagram for better understanding), and they will be zipped/compressed.
I want my batch script to be called like so:
BatchScript.bat "c:\temp\usd\Folder 0"
I'm using 7za.exe as the command line extraction tool.
What I want my batch script to do is to iterate through the "Folder 0"'s subfolders, and extract all of the containing ZIP files into their respective folder.
It is obligatory that the files extracted are in the same folder as their respective ZIP files. So, files contained in "File 1.zip" are needed in "Folder 1" and so forth.
I have read about the FOR...DO command on Windows XP Professional Product Documentation - Using Batch Files.
Here's my script:
#ECHO OFF
FOR /D %folder IN (%%rootFolderCmdLnParam) DO
FOR %zippedFile IN (*.zip) DO 7za.exe e %zippedFile
I guess that I would also need to change the actual directory before calling 7za.exe e %zippedFile for file extraction, but I can't figure out how in this batch file (through I know how in command line, and even if I know it is the same instruction "cd").
EDIT #1
I have already received some tips on ServerFault to the same question. Please see the answers at this link.
However, it extracted from the root (C:), and not from the given in parameter folder.
Anyone has an idea?
EDIT #2
It seems that batch script doesn't handle folder and file names containing a space character adequately. Can anyone confirm what I think?
EDIT #3
I need it to be fully recursive, since I don't know the directory structure against which this will be used.
EDIT #4.a
With #aphoria's solution, I'm almost there! The only problem is that it takes let's say File5.zip, retrieve the filename only to get File5, creates a subfolder File5 and extract the File5.zip to File5 subfolder, then, it wants to create a File5 subfolder in Folder 1, where it should instead want to create File1 subfolder, to stick with my example.
EDIT #4.b
As required, here's the code as it currently look:
#echo off
setlocal enableextensions enabledelayedexpansion
rem
rem Display instructions when no parameter is given.
rem
if "%1" equ "" (
echo Syntaxe : od.bat ^<directory mask>^
echo Exemple : od.bat *
goto :Eof
)
rem
rem Setting the PATH environment variable for this batch file for accessing 7za.exe.
rem
path=c:\temp;%PATH%
rem
rem Removing quotes from the given command line parameter path.
rem
set root=%1
set root=%root:~%1
set root=%root:~0,-1%
rem Searching directory structure from root for subfolders and zipfiles, then extracting the zipfiles into a subfolder of the same name as the zipfile.
for /F "delims==" %%d in ('dir /ogne /ad /b /s %root%') do (
echo Traitement du dossier : "%%d"
for /F "delims==" %%f in ('dir /b "%%d\*.zip"') do (
rem Getting filename without extension.
set subfolder=~n%f
mkdir "%%d\%subfolder%"
rem Extracting zipfile content to the newly created folder.
7za.exe e "%%d\%%f" -o"%%d\%subfolder%"
)
)
:Eof
endlocal
Ideas anyone?
My guess is that it digs one directory hierarchy at a time. Here's the deal. Consider we have a Folder A in Folder 1 (Folder 1\Folder A), then, it searches from Folder 1 through Folder 5, and comes back to Folder 1\Folder A, where the %subfolder% variable sticks with its last value.
Anyone's help is gratefully appreciated.
I'm not very familiar with the 7zip command-line options, so you will need to figure out the exact command for that, but the script below will take a fully specified path (spaces allowed) and print out the the folder name and .zip files contained within it.
#ECHO OFF
REM
REM Remove the double quotes from the front and end of the root path
REM
SET ROOT=%1
SET ROOT=%ROOT:~1%
SET ROOT=%ROOT:~0,-1%
ECHO %ROOT%
FOR /F "DELIMS==" %%d in ('DIR "%ROOT%" /AD /B') DO (
ECHO %%d
FOR /F "DELIMS==" %%f in ('DIR "%ROOT%\%%d\*.zip" /B') DO (
ECHO %%f
)
)
Run it like this:
MyScript.CMD "c:\temp\usd\Folder 0"
You should get output similar to this:
Folder A
File 1.zip
File 2.zip
Folder B
File 1.zip
File 2.zip
UPDATE
The code below will extract Folder A\File 1.zip to a new folder Folder A\File 1.
A few things to keep in mind:
In the first FOR loop, you need to have %ROOT% enclosed in double quotes to handle folders with spaces in the name.
Since you're SETting a variable inside the second FOR, you need to put SETLOCAL ENABLEDELAYEDEXPANSION at the beginning. Then, reference the variable using ! (for example, !subfolder!) to force expansion at runtime.
This line of your code set subfolder=~n%f should be this set subfolder=%%~nf
I put ECHO in front of the MKDIR and 7za.exe commands to test. Once you are sure it is doing what you want, remove the ECHO statement.
Here is the code:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM
REM Remove the double quotes from the front and end of the root path
REM
SET ROOT=%1
SET ROOT=%ROOT:~1%
SET ROOT=%ROOT:~0,-1%
ECHO %ROOT%
REM Searching directory structure from root for subfolders and zipfiles,
REM then extracting the zipfiles into a subfolder of the same name as the zipfile.
FOR /F "delims==" %%d IN ('dir /ogne /ad /b /s "%ROOT%"') DO (
ECHO Traitement du dossier : "%%d"
FOR /F "delims==" %%f IN ('dir /b "%%d\*.zip"') DO (
REM Getting filename without extension.
SET subfolder=%%~nf
ECHO mkdir "%%d\!subfolder!"
REM Extracting zipfile content to the newly created folder.
ECHO 7za.exe e "%%d\%%f" -o"%%d\!subfolder!"
)
)
ENDLOCAL

Resources