自动将文件从一个地方复制到另一个地方

自动将文件从一个地方复制到另一个地方

我有一个愚蠢的问题,但我想知道如何使用 .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 算法,该算法提供了一种非常快速的方法来同步远程文件。

它应该可以满足您陈述的需求。

相关内容