使用 Bat 文件复制和重命名

Posted

技术标签:

【中文标题】使用 Bat 文件复制和重命名【英文标题】:Copy and Rename with Bat File 【发布时间】:2021-07-21 21:17:21 【问题描述】:

我也在 (https://www.mrexcel.com/board/threads/copy-and-rename-with-bat-file.1169385/) 上发布了这个问题 我已经阅读了很多关于此的帖子,并解决了我使用以下代码复制和重命名文件的问题之一,但是当我试图理解本网站上有关此主题的一些帖子时,我仍然感到不知所措。

xcopy "M:\abc.csv" "O:\File"
set HR=%time:~0,2%
set HR=%Hr: =0%
set HR=%HR: =%
rename "O:\File\abc.csv" "x_%date:~10,4%-%date:~4,2%-%date:~7,2%_%HR%%time:~3,2%.csv"

我的输出是文件名 = x_YYYY-MM-DD_TTTT.csv,我不明白所有变量是如何工作的,但我需要让这个 bat 文件将 abc.csv 文件重命名为“MM- DD-YYYY-#XXX.csv”。 “#”将是一个增量值,具体取决于一天内重命名了多少文件(需要从第二天开始),“XXX”只是每个文件的设置文本值。 abc.csv 每天都将具有相同的名称。我开始玩脚本,但我卡住了。我知道我错过了增量部分。

xcopy "M:\abc.csv" "P:\File"
set HR=%time:~0,2%
set HR=%Hr: =0%
set HR=%HR: =%
rename "P:\File\abc.csv" "%date:~4,2%-%date:~7,2%-%date:~10,4%XXX.csv"

最后一个问题将出现在我正在复制和重命名的文件夹中,它们将有 3 个文件(abc.csv、def.csv、hij.csv),所有 3 个文件都将被复制和重命名.相同的日期和增量格式,但具有不同的“XXX”文本。你是把所有这些都放在一个 bat 文件中(我假设你不能在同一个脚本中容纳所有这些,你必须做单独的行)还是你把它分成 3 个不同的 bat 文件?

我已经用实际的文件名和目录编辑了代码,也取得了一点进展。当您运行echo ren 并且它输出多行并且它们都是相同的输出“04-28-2021-1Custinfo.txt”时,这是否意味着代码的增量部分不起作用?

@echo off
 setlocal enabledelayedexpansion
  for /d /r %%a in (*) do (
    set n=0
    set HR=%time:~0,2%
    set HR=%Hr: =0%
    set HR=%HR: =%   
    pushd "P:\Jarett\SM_TEST\IN"
      for /f "delims=" %%b in (' dir /b /a-d 2^>nul ') do (
        set /a n=n+1
           set num=0!n!
           echo ren "P:\Jarett\SM_TEST\IN\Header3.txt" "%date:~4,2%-%date:~7,2%-%date:~10,4%-!num:~-1!%Custinfo.txt"
    )
   popd
  )
pause

我觉得很好,尝试了我找到的其他代码,但是当我第二次运行它时,它将 Header3.txt 文件作为 Header3.txt 保存在最终目标文件夹中。当我第二次运行 bat 文件时,我试图让它保存为 04-29-2021-2Custinfo.txt。我将始终拉取文件 Header3.txt 是否重要,这就是为什么它不算数?

xcopy "M:\Sage 100 Advanced\2018\MAS90\John\MAS_Mirror\SM_TEST\IN\Header3.txt" "P:\Jarett\SM_TEST\IN" 
rem Presumes %date% returns Ddd DD/MM/YYYY so may need adjusting if American format
set today=%date:~4,2%-%date:~7,2%-%date:~10,4%
echo %today%
echo "Moving today's files to temp"
mkdir C:\Users\jarett.AS\temp
move %today%* temp
move Header3.txt temp
cd temp
set count=0
for %%x in (Header3.txt) do (set /a count+=1)
set count=00%count%
set count=%count:~-1%
rename "P:\Jarett\SM_TEST\IN\Header3.txt" "%today%-%count%Custinfo.txt"
move *.txt ..

这是我终于开始工作的代码。一直在玩它以完全理解一切并尝试不同的事情。我尝试将 Header3.txt rename Header3.txt %today%-%count%Custinfo%count%.txt 重命名,但每次都将其重命名为 04-30-2021-1Custinfo1.txt。有人可以指出我需要进一步研究的领域吗?

set today=%date:~4,2%-%date:~7,2%-%date:~10,4%
if not exist .\temp mkdir temp
move %today%* temp
xcopy "M:\Sage 100 Advanced\2018\MAS90\John\MAS_Mirror\SM_TEST\IN\Header3.txt" "P:\Jarett\SM_TEST\IN"
move P:\Jarett\SM_TEST\IN\Header3.txt temp
cd temp
set count=0
for %%x in (*.txt) do (set /a count+=1)
set count=00%count%
set count=%count:~-1%
rename Header3.txt %today%-%count%Custinfo.txt
move *.txt P:\Jarett\SM_TEST\IN

【问题讨论】:

SET 命令语法在SET 命令的帮助文件中有清楚的解释。打开命令提示符并输入:set /?. 还有数百个示例说明如何以不依赖于 PC、区域设置或用户设置的方式正确检索日期和时间的各个组成部分。我建议你应该把你的任务分解成更小的任务,一旦你完成了每一个任务,试着把它们合并成一个解决方案。目前,您需要的健壮代码是对几个不同问题的答案,(并且可能需要进一步解释abcXXX 之间的相关性)。 可能是实际源文件名和它们各自生成的目标文件名! 如果您可以解释使用xcopy.exe 来执行单个复制命令而不是内部copy 命令本身是否有特定原因,它也可能会有所帮助。我可能会建议将具有新名称的文件复制为单个命令可能会更好,而不是将文件复制为一个命令,然后将该文件重命名为单独的命令。 @Compo 不知道如何使用xcopy 进行推理,这是我第一次完成一项简单任务。 ROBOCOPY 也有效,但之后我在代码上苦苦挣扎。 abcxxx 之间没有关联,xxx 实际上将是一个较长的文本字符串。这将是实际的源文件名“P:\Jarett\SM_TEST\IN\Header.txt”,这就是我希望输出为“04-28-2021-1Custinfo.txt” 打开命令提示符窗口,键入copy /?,按[ENTER] 键,然后阅读显示的输出。您也可以对rename /?set /?xcopy /?robocopy /? 执行相同操作,以获取他们的帮助和使用信息。请不要忽略本网站每个页面顶部的搜索框,它可以帮助您找到将日期和时间组件转换为所需格式的示例。 【参考方案1】:

有些计数不清楚,但如果您想更改,可以进行。

例如,不清楚您想要如何编号,是否可以,或者您是否想要为每个 XXX 编号

试试这个代码:

@echo off & setlocal EnableDelayedExpansion

cls

set sizemax=130
mode con: COLS=%sizemax% LINES=35

rem create "box" macro "Box"
set "Box=call :box"

%Box% "Prepare the test environment ..."
pause

cd %tmp%
mkdir TEST 2>nul
mkdir Jarett 2>nul

set "source_folder=%tmp%\TEST"
set "destination_folder=%tmp%\Jarett"

echo >%source_folder%\abc.csv
echo >%source_folder%\def.csv
echo >%source_folder%\hij.csv

%Box% "Source Folder"
dir %source_folder% & pause

%Box% "Destination Folder"
dir %destination_folder% & pause 

cls
%Box% "Test the script." & pause

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
setlocal EnableDelayedExpansion

rem set source and destination directory/folder
rem remove rem before using the script in production environment in the following two lines
rem set "source_folder=M:\TEST"
rem set "destination_folder=P:\Jarett"

rem assume all file of type and extension "CSV"

rem create 3 variable for the file name. You can change the name of the file abc,def,hij
set "File1=abc"
set "File2=def"
set "File3=hij"

rem create a map and lookup that associate abc with XXX01, def with XXX02, hij with XXX03. You can change the string XXX01, XXX02, XXX03
SET map=!File1!-XXX01;!File2!-XXX02;!File3!-XXX03;
%Box% "map=!map!" & pause

for %%N in (!File1!, !File2!, !File3!) do (

  rem Set the "today" variable. Choice the correct for you language setting and delete/comment others.
  set "today=%date:~7,2%-%date:~4,2%-%date:~10,4%"
  set "today=%date:~4,2%-%date:~7,2%-%date:~10,4%"
  set "today=%date:~3,2%-%date:~0,2%-%date:~6,4%" & rem italian default to MM-DD-YYYY
  %Box% "file:%%N today=!today!" & pause

  rem Count today csv, add 1 and prepare to pad.
  for /f %%f in (' dir !destination_folder!\!today!*.csv /b /a-d 2^>nul ^| find /c /v "" ') do set /a "count=%%f+10001"
  %Box% "file:%%N count=!count!" & pause

  rem prepare time part
  set "now=!time:~0,-3!" & set "now=!now: =0!" & set "now=!now::=.!"
  %Box% "file:%%N now=!now!" & pause

  call :lookup_XXX_map %%N
  %Box% "file:%%N XXX=!XXX!" & pause

  %Box% "move !source_folder!\%%N.csv !destination_folder!\!today!_!now!_!count:~-3!_!XXX!.csv" & pause
  move !source_folder!\%%N.csv !destination_folder!\!today!_!now!_!count:~-3!_!XXX!.csv

  %Box% "Destination Folder"
  dir !destination_folder! & pause
)

echo Exit/End ... & pause

goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:box
  set "s=%~1"
  set /A s1=%sizemax%-1, s2=s1-1
  set "l="
  for /L %%B in (1,2,%sizemax%) do set "l=!l!--" & if "!s:~%s1%,1!" == "" set "s= !s! "
  set "s=!s:~1,%s2%!"
  set "l=!l:~0,%s2%!"
  for %%B in ("" "+%l%+" "|%s%|" "+%l%+" "") do echo(%%~B
goto :eof

:lookup_XXX_map
  CALL SET XXX=%%map:*%1-=%%
  SET XXX=%XXX:;=&:%"
goto :eof

您必须为“DATE”变量选择正确的布局。然后就可以运行了。

当测试没问题时,像这样删除多余的行:

@echo off
setlocal EnableDelayedExpansion

rem set source and destination directory/folder
set "source_folder=M:\TEST"
set "destination_folder=P:\Jarett"

rem assume all file of type and extension "CSV"

rem create 3 variable for the file name. You can change the name of the file abc,def,hij
set "File1=abc"
set "File2=def"
set "File3=hij"

rem create a map and lookup that associate abc with XXX01, def with XXX02, hij with XXX03. You can change the string XXX01, XXX02, XXX03
SET map=!File1!-XXX01;!File2!-XXX02;!File3!-XXX03;

for %%N in (!File1!, !File2!, !File3!) do (

  rem Set the "today" variable. Choice the correct for you language setting and delete/comment others.
  set "today=%date:~7,2%-%date:~4,2%-%date:~10,4%"

  rem Count today csv, add 1 and prepare to pad.
  for /f %%f in (' dir !destination_folder!\!today!*.csv /b /a-d 2^>nul ^| find /c /v "" ') do set /a "count=%%f+10001"

  rem prepare time part
  set "now=!time:~0,-3!" & set "now=!now: =0!" & set "now=!now::=.!"
 
  call :lookup_XXX_map %%N
  
  move !source_folder!\%%N.csv !destination_folder!\!today!_!now!_!count:~-3!_!XXX!.csv

)

echo Exit/End ... & pause

goto :eof

:lookup_XXX_map
  CALL SET XXX=%%map:*%1-=%%
  SET XXX=%XXX:;=&:%"
goto :eof

【讨论】:

以上是关于使用 Bat 文件复制和重命名的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CopyWebpackPlugin 复制和重命名文件

文件复制和重命名

使用Python复制和重命名excel文件[重复]

使用创建日期复制和重命名文件(批处理脚本)

如何在 Linux 中批量移动复制追加和重命名文件

如何使用shell复制和重命名多个文件