Archive files with certain extension
So I need a Windows Script that I can tell it a directory to go through and it will parse all sub-directories and while in each subdir, will archive all files with a certain file extension and keep it in the same subdir, then move onto the next one.
What's the best way to go about this? Perl Automation Script开发者_StackOverflow社区ing, AutoIt?
Any sample code you guys can give me?
Perl is more powerful than batch scripts but since Perl is not included with windows it seems overkill for tasks such as this one. This should for example work:
FOR /R C:\hello\ %%G IN (*.txt) DO "c:\Program Files\7-Zip\7z.exe" a %%G.zip %%G && del %%G
Note that you cannot do this directly in the prompt, you must save it as a .bat file. It is of course also possible to allow the user to specify the paths and extensions with command line like this:
FOR /R %1 %%G IN (%2) DO "c:\Program Files\7-Zip\7z.exe" a %%G.zip %%G && del %%G
More information about FOR and other windows command line commands can be found here: http://ss64.com/nt/
This would then be run with:
test.bat C:\Hello\ *.txt
EDIT: This obviously requires you to have 7-Zip installed but it's pretty obvious where to change the code if you want to use some other zipper. Also keep in mind to always be Extremely careful when experimenting with scripts such as this. One small mistake could have it delete a lot of files, so you should always test it on a copy of the file system until you are absolutely sure it works.
FORFILES is included with Windows and may be more applicable than FOR to what you're trying to do:
FORFILES [/P pathname] [/M searchmask] [/S] [/C command] [/D [+ | -] {MM/dd/yyyy | dd}]
Description: Selects a file (or set of files) and executes a command on that file. This is helpful for batch jobs.
Parameter List:
/P pathname Indicates the path to start searching. The default folder is the current working directory (.). /M searchmask Searches files according to a searchmask. The default searchmask is '*' . /S Instructs forfiles to recurse into subdirectories. Like "DIR /S". /C command Indicates the command to execute for each file. Command strings should be wrapped in double quotes. The default command is "cmd /c echo @file". The following variables can be used in the command string: @file - returns the name of the file. @fname - returns the file name without extension. @ext - returns only the extension of the file. @path - returns the full path of the file. @relpath - returns the relative path of the file. @isdir - returns "TRUE" if a file type is a directory, and "FALSE" for files. @fsize - returns the size of the file in bytes. @fdate - returns the last modified date of the file. @ftime - returns the last modified time of the file. To include special characters in the command line, use the hexadecimal code for the character in 0xHH format (ex. 0x09 for tab). Internal CMD.exe commands should be preceded with "cmd /c". /D date Selects files with a last modified date greater than or equal to (+), or less than or equal to (-), the specified date using the "MM/dd/yyyy" format; or selects files with a last modified date greater than or equal to (+) the current date plus "dd" days, or less than or equal to (-) the current date minus "dd" days. A valid "dd" number of days can be any number in the range of 0 - 32768. "+" is taken as default sign if not specified.
Below one way I would do it in AutoIt since you asked. Replace the MsgBox line with whatever code you need to do whatever it is your wanting to do. AutoIt is fun stuff!
#include <File.au3>
archiveDir(InputBox("Path","Enter your start path."))
Func archiveDir($rootDirectory)
$aFiles = _FileListToArray($rootDirectory)
For $i = 1 To UBound($aFiles) - 1
If StringInStr(FileGetAttrib($aFiles[$i]),"D") Then archiveDir($rootDirectory & $aFiles[$i] & "\")
MsgBox(0,"This would be your archive step!",'"Archiving" ' & $rootDirectory & $aFiles[$i])
Next
EndFunc
One solution could be:
my $dirCnt = 0;
traverse_directory('C:\Test');
sub traverse_directory{
my $directory = shift(@_);
$dirCnt++;
my $dirHandle = "DIR".$dirCnt;
opendir($dirHandle, $directory);
while (defined(my $file = readdir($dirHandle))){
next if $file =~ /^\.\.?$/; # skip . and .. ...
if (-d "$directory\\$file"){ traverse_directory("$directory\\$file"); }
if ($file =~ /\.txt/){ #find txt files, for example
print "$file\n"; #do something with the text file here
}
}
closedir($dirHandle);
}
精彩评论