我有一个愚蠢的问题,但我想知道如何使用 .bat 文件执行以下操作,甚至知道是否可能。
我有一个文件,有人将它放在不在我的网络上的服务器上的文件夹中(但我们有权访问,因为我们在域中),因此,我必须搜索最新的文件并将其复制到我的网络中的文件夹中。
我卡在了选择“最新文件”的部分
任何想法都将非常受欢迎:)
答案1
我最近编写了一个 Perl 脚本,它正是用于实现这一点的。当您启动此脚本时,它会搜索是否有较新的 ZIP 文件,复制它、提取它、修改配置文件并启动 EXE。也许您不想做所有这些,但如果您想修改/使用它,我会在这里发布它。
#!/usr/bin/perl
# get_latest_executable.pl v0.5
# Usage: perl get_latest_executable.pl test4|test6 [country] [language]
###############
# YD @ 02/09/2011
# 05/09/2011 Multiple transparent compression options
# Fixed config file backup
# Removed useless debug code
# 12/09/2011 Added external configuration file
# Removed internal arrays with options, script argument is trusted now
# 15/09/2011 Added informing latest executable date
# More comments and intro
# 19/09/2011 Bug retreiving versions higher than 99 (fixed)
# Now checking latest executable is done on file creation time and no longer using version
# 27/09/2011 Fixed extra trailing \ on destination path
# 28/09/2011 Added commenting out all user.dll's updateUserConfiguration entry
# Now user.dll file is parsed until the end, and does not stop when first searched entry is found
###############
use strict;
use File::stat;
use File::Path qw(make_path remove_tree);
use File::Copy;
use constant VERSION => "v0.5";
use constant TIMESTAMP_FORMAT => "%02d:%02d %02d/%02d/%4d"; # Formato del informe de fecha
##########
# Args
##########
use constant MIN_ARGS => 0;
use constant MAX_ARGS => 2;
##########
# Indexes
##########
use constant IDX_TEST4 => 0;
use constant IDX_TEST6 => 1;
my $executable_branch;
##########
# Paths
##########
my $path_source;
# Where to copy the executable in local
my $path_destination;
# Where to search for latest executable
my $path_latest_executable;
##########
# File names
##########
# SGCV10 executable name
my $executable_name = 'gccom.exe';
# SGCV10 config file name
my $config_file = "user.dll";
# Script configuration file
my $config = "config.txt";
##########
# Compressors
##########
my @compressors = ('"C:\Archivos de programa\7-Zip\7z.exe" x -y ', '"C:\Archivos de programa\WinZip\winzip32.exe" -e ');
##########
# SGCV10 configuration
##########
my $do_config_changes = "";
my $backup_prefix = '.bak';
my $country = "es";
my $country_option = '(^COUNTRY=)';
my $lang = "ES";
my $lang_option = '(^LANGUAGE=)';
my $update_option = '^updateUserConfiguration=';
##########
# Script configuration
##########
my $source = '^SOURCE=(.*)\n';
my $destination = '^DESTINATION=(.*)\n';
# Checks arguments received by the script
sub check_args()
{
if ($#ARGV > MAX_ARGS || $#ARGV < MIN_ARGS)
{
print(STDERR "Numero de argumentos incorrecto\n");
print(STDERR "Uso: perl get_latest_executable.pl test4|test6 [country] [language]\n");
exit();
}
$executable_branch = $ARGV[0];
if ($#ARGV >= 1)
{
$do_config_changes = "1";
$country = $ARGV[1];
}
if ($#ARGV == 2)
{
$lang = uc($ARGV[2]);
}
}
# Returns true if file "a" is newer than file "b"
sub is_newer_version
{
my ($a_path, $b_path) = @_;
my $ret = "1";
if ($b_path ne "")
{
my $a_time = stat($a_path)->mtime;
my $b_time = stat($b_path)->mtime;
$ret = $a_time > $b_time;
}
return $ret;
}
# Receives executable directory
# Returns latest zip full path
sub get_latest_zip_full_path
{
my $path = shift;
my $ret;
if (-d $path)
{
opendir(DH, $path) or die ("No se pudo abrir el directorio: $path\n");
my @dir = readdir(DH);
close(DH);
my $newest = 0;
for(@dir)
{
my $full_path = $path.$_;
if (-f $full_path && $_ =~ m/zip/i)
{
my $cur_file_time = stat($full_path)->mtime;
if($cur_file_time > $newest)
{
$newest = $cur_file_time;
$ret = $full_path;
}
}
}
}
return $ret;
}
# Returns true if local executable is OLDER than remote executable, false otherwise
# Creates local directory if not found, deletes older executable .ZIP and directory
sub check_local_delete
{
my ($local_dir, $local_latest, $remote_path) = @_;
my $ret = "";
# Local directory exists
if(-d $local_dir)
{
if (is_newer_version($remote_path, $local_latest))
{
print(STDERR "Borrando ejecutable obsoleto: $local_latest\n");
# Delete older local ZIP
unlink($local_latest);
# Delete old directory
$local_latest =~ s/\.zip//;
if (-d $local_latest)
{
remove_tree($local_latest);
}
$ret = "1";
}
}
# Local directory does not exist, create it and return remote newer
else
{
make_path($local_dir);
$ret = "1";
}
return $ret;
}
# Given a full path, returns filename only
sub get_filename_from_full_path
{
my $full_path = shift;
my $ret = reverse($full_path);
$ret =~ m/\\/;
$ret = $`;
$ret = reverse($ret);
return $ret;
}
# Modifies SGCv10 configuration
sub make_config_changes
{
my $path = shift;
my $config_path = $path.$config_file;
if (-f $config_path)
{
open(FD, '<'.$config_path);
my @config = <FD>;
close(FD);
# Backup original file (only if not backed up already!!!)
if (!(-f $config_path.$backup_prefix))
{
copy($config_path, $config_path.$backup_prefix);
}
# Modify it
my $i = 0;
while($i <= $#config)
{
if ($config[$i] =~ /$country_option/)
{
$config[$i] = $1.$country."\n";
}
if ($config[$i] =~ /$lang_option/)
{
$config[$i] = $1.$lang."\n";
}
if ($config[$i] =~ /$update_option/)
{
$config[$i] = "//" . $config[$i];
}
$i++;
}
# Write it
open(FD, '>'.$config_path);
print(FD @config);
close(FD);
}
else
{
print(STDERR "WARNING: config file $config_path not found!\n");
}
}
# Selects best command to decompress with
sub get_best_compressor
{
my $ret;
my $i = 0;
my $found = "";
while($i <= $#compressors && !$found)
{
$compressors[$i] =~ m/\"(.*)\"/;
if (-f $1)
{
$ret = $compressors[$i];
$found = "1";
}
}
if (!$found)
{
$ret = -1;
}
return $ret;
}
# Reads and applies configuration file
sub read_config
{
open(FD, '<'.$config) or die "No se encontro el fichero de configuracion $config\n";
my @config = <FD>;
close(FD);
# Source
my @source_list = grep(/$source/, @config);
my $src = $source_list[0];
$src =~ /$source/;
$src = $1;
if (substr($src, -1, 1) ne "\\")
{
$src .= "\\";
}
$path_latest_executable = uc("$src$executable_branch\\");
# Destination
my @dest_list = grep(/$destination/, @config);
$path_destination = $dest_list[0];
$path_destination =~ /$destination/;
$path_destination = uc($1);
if (substr($path_destination, -1, 1) ne "\\")
{
$path_destination .= "\\";
}
}
# Formatea el tiempo
sub format_timestamp
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @_;
return sprintf(TIMESTAMP_FORMAT, $hour, $min, $mday, $mon+1, $year+1900);
}
# Basurilla
sub intro
{
print(STDERR "AutoEjecutable " . VERSION . " by Obi Perl Kenobi\n\n");
}
#############
# MAIN
#############
# Show intro
intro();
# Checking arguments
check_args();
# Read configuration file
read_config();
if (!(-d $path_latest_executable))
{
print(STDERR "No se ha encontrado el directorio origen $path_latest_executable\n");
exit();
}
# Getting latest executable
my $latest_zip_full_path = get_latest_zip_full_path($path_latest_executable);
# Getting time stamp
my $latest_zip_time = format_timestamp(localtime(stat($latest_zip_full_path)->mtime));
print(STDERR "Ultimo ejecutable disponible: $latest_zip_full_path -> $latest_zip_time\n");
# Checking if latest executable newer than local
$path_destination .= $executable_branch."\\";
if (check_local_delete($path_destination, get_latest_zip_full_path($path_destination), $latest_zip_full_path))
{
print(STDERR "El ejecutable remoto es mas reciente ($latest_zip_time), copiando... ");
# Copying executable to local
copy($latest_zip_full_path, $path_destination);
}
else
{
print(STDERR "No hay cambios!\n");
}
my $path_aux = $path_destination.get_filename_from_full_path($latest_zip_full_path);
my $local_exe_dir = $path_aux;
$local_exe_dir =~ s/\.zip//;
$local_exe_dir .= "\\";
if (-f $path_aux && !(-d $local_exe_dir))
{
# Choose extractor
my $extractor_command = get_best_compressor();
if ($extractor_command == -1)
{
print(STDERR "No se pudo encontrar ningun programa de descompresión. Por favor modifique las rutas en el script si no usa la instalación por defecto\n");
exit();
}
# Extract ZIP
chdir($path_destination);
print(STDERR "Extrayendo...\n");
$extractor_command .= '"' . $path_aux . '"';
system($extractor_command);
}
chdir($local_exe_dir);
if ($do_config_changes)
{
print(STDERR "Modificando configuracion para pais $country y lengua $lang...\n");
make_config_changes($local_exe_dir);
}
my $local_exe = '"' . $local_exe_dir.$executable_name . '"';
print(STDERR "Lanzando el ejecutable $local_exe de las $latest_zip_time\n");
system($local_exe);
get_latest_zip_full_path() 子例程执行您所要求的操作。
它使用外部配置文件,如下所示:
SOURCE=J:\Ejecutables\
DESTINATION=D:\SGCv10\ejecutables\
这不会“按原样”解决您的问题。您可以随意修改和使用,也可以提出您的要求。
答案2
对于这些类型的任务,您应该查看 robocopy。它是早期 Windows 版本资源工具包的一部分,但现在它已成为 Win2k8 服务器和 Windows 7 的一部分。有一整套文件选择选项可帮助完成此任务。
答案3
这将镜像目录树。从源复制不同的文件,并删除目标中的多余文件
ROBOCOPY source destination /MIR
这将复制子目录(包括空目录),但排除旧文件。
ROBOCOPY source destination /E /XO
答案4
您可以尝试 Unix 远程复制工具的 Windows 版本rsync
,同步:
cwRsync 是 Rsync 和 Cygwin 的另一个封装。您可以使用 cwRsync 进行快速远程文件备份和同步。Rsync 使用 Rsync 算法,该算法提供了一种非常快速的方法来同步远程文件。
它应该可以满足您陈述的需求。