【问题标题】:Copy a file using .bat to another location使用 .bat 将文件复制到另一个位置
【发布时间】:2018-02-06 05:32:17
【问题描述】:

是否可以使用通配符(而不是硬编码整个文件名)将文件从一个位置复制到另一个位置?另外,我想将 HHSS(小时和秒)附加到文件名。

示例:我们的系统每天都会生成几个文件,名称格式如下:

GL_YYYYMMDD.txt
AP_YYYYMMDD.txt

我想将这些文件复制/移动到另一个名为“Backups”的文件夹并附加 HHSS(小时和秒),因此文件名如下所示:

GL_YYYYMMDDHHSS
AP_YYYYMMDDHHSS

到目前为止我所拥有的:

Rem Determine date
Set mm1=%date:~4,2%
Set dd1=%date:~7,2%
Set yyyy1=%date:~10,4%

REM Determine Time
Set HH=%time:~0,2%
IF "%HH:~0,1%" == " " SET HH=0%HH:~1,1%
Set MM=%time:~3,2%
Set SEC=%time:~6,2%
Set runtime=%HH%%MM%%SEC%

rem Seconday date backup
cd E:\Blackline\DailyFiles

copy GL* E:\Blackline\Backups\"GL*%runtime%"

pause

【问题讨论】:

  • 使用FOR 命令列出您要处理的文件。然后,您可以获得要复制到输出的确切输出文件名。
  • 问题是,文件名每天都在变化。今天的文件名是 GL_20170828,明天是 GL_20170829,所以我不知道如何将此文件复制到备份文件夹并将 HHSS 添加到其名称中(GL_201708280547)。另外,我对批处理脚本非常陌生。
  • 我只能假设yyyyMMdd 与特定文件相关。将当前时间附加到该名称没有任何意义,因为该时间仅与批处理命名过程有关,而不与文件本身有关。使用文件创建时间不是更好、更相关的追加内容吗?
  • YYYYMMDD 是从我们的系统创建文件的日期。另外,这也是我们第三方要求的命名格式。这就是我考虑将 HHMM 添加到此名称的原因,以便万一我们必须在一天内因未知原因创建两个文件,可以对其进行处理和保存。
  • 在这种情况下需要考虑粒度。是否有可能在同一分钟内生成两个文件? (在这种情况下,可能不会;但这是一个值得提出的问题。)同一秒?同一厘秒?只是对未来使用的想法;您描述的情况表明这确实不太可能成为问题。

标签: batch-file file-copying


【解决方案1】:

目标文件规范中的星号通配符 (*) 仅适用于文件名的相同列从源到目标的精确复制,由最后一个点 (.) 终止和重新启动,因为它传统上代表文件类型或“扩展名”:

M:\t\a>dir
 Volume in drive M is MyDrive
 Volume Serial Number is ABCD-EF01

 Directory of M:\t\a

08/28/2017  05:42 PM    <DIR>          .
08/28/2017  05:42 PM    <DIR>          ..
08/28/2017  05:42 PM                17 test1.dat
08/28/2017  05:42 PM                17 test2.dat
08/28/2017  05:42 PM                17 test3.dat
               3 File(s)             51 bytes
               2 Dir(s)   1,050,894,336 bytes free

M:\t\a>copy test*.dat ..\b\test*.abc
test1.dat
test2.dat
test3.dat
        3 file(s) copied.

M:\t\a>dir ..\b
 Volume in drive M is MyDrive
 Volume Serial Number is ABCD-EF01

 Directory of M:\t\b

08/28/2017  05:44 PM    <DIR>          .
08/28/2017  05:44 PM    <DIR>          ..
08/28/2017  05:42 PM                17 test1.abc
08/28/2017  05:42 PM                17 test2.abc
08/28/2017  05:42 PM                17 test3.abc
               3 File(s)             51 bytes
               2 Dir(s)   1,050,894,336 bytes free

M:\t\a>

要在文件名中插入其他组件,您需要一次获取一个。我推荐一个FOR 循环。

旁注:请注意日期和时间提取中可能存在的空格。例如,检查上午 9 点是否表示为 "09:00" 而不是 " 9:00"

这是一个使用您提出的机制来获取时间的FOR 循环的快速示例(我做了没有确认早上工作):

@echo off
REM Determine Time
Set HH=%time:~0,2%
IF "%HH:~0,1%" == " " SET HH=0%HH:~1,1%
Set MM=%time:~3,2%
Set SEC=%time:~6,2%
Set runtime=%HH%%MM%%SEC%

for %%F in (test*.dat) do copy "%%F" "..\b\%%~nF%runtime%%%~xF"

这会产生以下结果,将时间附加到文件名的 test1/test2/test3 部分的末尾:

M:\t\a>dir
 Volume in drive M is MyDrive
 Volume Serial Number is ABCD-EF01

 Directory of M:\t\a

08/28/2017  05:42 PM    <DIR>          .
08/28/2017  05:42 PM    <DIR>          ..
08/28/2017  05:51 PM               227 copywithtime.bat
08/28/2017  05:42 PM                17 test1.dat
08/28/2017  05:42 PM                17 test2.dat
08/28/2017  05:42 PM                17 test3.dat
               3 File(s)             51 bytes
               2 Dir(s)   1,050,894,336 bytes free

M:\t\a>copywithtime
        1 file(s) copied.
        1 file(s) copied.
        1 file(s) copied.

M:\t\a>dir ..\b
 Volume in drive M is MyDrive
 Volume Serial Number is ABCD-EF01

 Directory of M:\t\b

08/28/2017  05:44 PM    <DIR>          .
08/28/2017  05:44 PM    <DIR>          ..
08/28/2017  05:42 PM                17 test1175134.dat
08/28/2017  05:42 PM                17 test2175134.dat
08/28/2017  05:42 PM                17 test3175134.dat
               3 File(s)             51 bytes
               2 Dir(s)   1,050,894,336 bytes free

M:\t\a>

【讨论】:

  • 嗯.. 如果您将* 称为它的实际名称 - 星号会更好吗?
  • 还要注意时间取决于本地,我在我的 zh-TW 机器上没有得到正确的结果,虽然这在 OP 的机器上工作
  • @SteveFest 我不明白关于通配符的问题。你能稍微扩展一下这个问题吗?
  • * asterisk,所以我认为如果你的回答叫它asterisk而不是star会更好。
  • @SteveFest 哦,哈哈,明白了。实际上,虽然它在英语中被称为星号,但在 DOS 中(它被用作通配符)总是被称为“星号”。就像“句号”被称为“点”一样。只是那些遗留/行话之一。 :-)
【解决方案2】:

试试这个。如果您删除 .txt 扩展名,复制文件,然后重新添加扩展名,您最终复制的文件将保留其原始名称和添加的时间戳。

Rem Determine date
Set mm1=%date:~4,2%
Set dd1=%date:~7,2%
Set yyyy1=%date:~10,4%

REM Determine Time
Set HH=%time:~0,2%
IF "%HH:~0,1%" == " " SET HH=0%HH:~1,1%
Set MM=%time:~3,2%
Set SEC=%time:~6,2%
Set runtime=%HH%%MM%%SEC%

rem Seconday date backup
cd E:\Blackline\DailyFiles

rename *.txt *.

copy GL* E:\Blackline\Backups\GL*%runtime%.txt

rename *. *.txt


pause

【讨论】:

  • 请注意,这是独立于语言环境的 - 我得到 /0 代表 mm1/3 代表 dd1,我得到了 yyyy1 的工作日,尽管这适用于 OP 的机器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多