根据字母文件名批量移动文件?

问题描述

我正在尝试重写我们使用的这个脚本(已编辑服务器名称),以解决工作中的问题。

:asc
if Exist \\SERVER01\import\process\*.asc (goto :SERVER02) ELSE (goto :process)
:SERVER02
if Exist \\SERVER02\import\process\*.asc (goto :end) ELSE (goto :process2)

:process
IF EXIST E:\import\*.asc (
goto :filefound) ELSE (goto :filenotfound)

:filefound
 FOR /f "delims=" %%a in ('dir "e:\import\*.asc" /t:a /o:d /b') do (
  echo %%a
  set file=%%a
goto :break
 )

 :break
 %file%
 robocopy e:\import\ \\SERVER01\import\process\ "%file%" /copy:DAT /mov
goto :end


:process2
IF EXIST E:\import\*.asc (
goto :filefound) ELSE (goto :filenotfound)

:filefound
 FOR /f "delims=" %%a in ('dir "e:\import\*.asc" /t:a /o:d /b') do (
  echo %%a
  set file=%%a
  goto :break2
 )

 :break2
 %file%
 robocopy e:\import\ \\SERVER02\import\process\ %file% /copy:DAT /mov
goto :end

:filenotfound
Echo There are no .asc files at this time)

:end
robocopy \\SERVER01\import\archive\ e:\import\archive\ /copy:DAT /is /mov /xx
robocopy \\SERVER02\import\archive\ e:\import\archive\ /copy:DAT /is /mov /xx

最初设置此脚本是为了平衡两个处理应用程序之间的所有文件,这取决于一个应用程序是否已经有一个正在处理的文件,它会将其提供给另一个...但现在我需要对文件名,并且仅将某些字母范围导出到每个处理服务器。所以我认为这意味着不是一次移动一个,我们只是将当时位于存储库文件夹中的所有 .ASC 文件分开,然后将一半移动到一个服务器,另一半移动到另一个(然后将由应用程序一次选择一个)。

我们有 .ASC 文件,其中包含客户端的数据(使用旧的专有应用程序写入 sql)。他们被命名为 CLIENTNAME.asc,我们有大约 200 个客户。该软件的使用或其功能无法更改,因此为了加快文件处理速度,我们创建了两个运行该应用程序的服务器。然后我将一个小的 CMD 脚本放在一起,它查看这些文件的中央存储库,并将它们作为一种负载平衡器分发到每个服务器之间。我们发现的问题是,如果同时处理同一客户端的两个文件一个一个服务器进行处理,另一个到另一个服务器),则会导致如何将其导入 sql 的问题。

所以我脑海中的解决方案是让脚本将所有以 .ASCA 开头的 O 文件移动到一台服务器,而那些以 L 开头的文件} 到 Z 转到另一个。然后我会处理这些字母范围以确保正确平衡。这意味着所有具有相同名称的客户端文件都将转到同一台服务器,该服务器一次处理这些文件,从而解决重复问题。

但是,我不知道怎么说“IF filename = "A-O".asc move here...”,所以我希望有人能帮我解决这个问题。

如您所见,此批处理文件在本地存储库服务器上运行。在 :asc 中,我们首先查看第一个进程服务器 SERVER01 上是否已经有任何 .ASC 文件。如果是这样,我们转到 :SERVER02,它会检查相同的内容。如果当前没有任何 .ASC 文件等待提取,则它会转到 :process,在那里检查本地存储库文件E:\import 是否有任何 .{{ 1}} 文件等待分发。如果是这样,它将将该文件移动到 ASC 以进行处理。然后脚本通过将一些存档文件(已处理的 SERVER01 文件)复制回存储库服务器来结束。然后在 ":process2" 中发生了类似的事情,但将它们移动到 .ASC 以进行处理。总的来说,这在两者之间提供了轻微的负载平衡。

我知道脚本非常混乱,当然可以用更多的字符串来修剪,而不是为每个服务器路径使用不同的函数,但希望您能大致了解。

解决方法

尝试在 Powershell 中执行此操作 - 这将立即复制 A-O 中的所有内容:

# Get the list of ASC files
$LocalFiles = Get-ChildItem "e:\import\*.asc"

# Check if any files exist
if (!$LocalFiles){Write-Output 'There are no .asc files at this time';break}

# Move the files based on first letter of the file name
$LocalFiles | Where Name -Match '^[A-O].*' | Move-Item -Destination \\SERVER01\import\process\ -Verbose
$LocalFiles | Where Name -Match '^[P-Z].*' | Move-Item -Destination \\SERVER02\import\process\ -Verbose

如果第一个字母不总是大写,请改用 [A-Oa-o]

如果你需要保留你的时间戳或属性,你将需要使用 robocopy 来代替:

$LocalFiles | Where Name -Match '^[A-O].*' | 
  foreach { robocopy src dst $_.name [...] }