[英]Batch File Variable to copy specific files
I'm trying to copy specific files from C:
to " X:
for example".我正在尝试将特定文件从
C:
复制到“例如X:
”。 The files are named with the same format.这些文件以相同的格式命名。
A1234_ZZabc123_DT1_F1.tst
A4567_ZZdef4567_DT2_F2.tst
A8901_ZZghi1289_DT1.tst
A2345_ZZjfkbu12_to_modify.tst
A6789_ZZlmny568_F1_to_modify.tst
A1234_ZZabc478_DT1.txt
I want to copy only the .tst
files, and with the same format as the first 3 Axxxx_ZZyyyxxx_DTx_Fx.tst
where x
=number and y
=letter.我只想复制
.tst
文件,格式与前 3 个Axxxx_ZZyyyxxx_DTx_Fx.tst
相同,其中x
= 数字, y
= 字母。
After ZZ, it might be 4 letters and 3 numbers, or 5 letters and 4 numbers, like a "namecode".在 ZZ 之后,它可能是 4 个字母和 3 个数字,或者 5 个字母和 4 个数字,就像一个“namecode”。 Example:
ZZkusha122
or ZZkus1551
.示例:
ZZkusha122
或ZZkus1551
。 I need to copy the folders along with the files too.我也需要将文件夹与文件一起复制。
I'm new to coding and really need some help.我是编码新手,真的需要一些帮助。
I need to find and copy all those files along 10k+ files together我需要找到所有这些文件并将其复制到 10k+ 个文件中
You claim that the first 3 of your example filenames fit the pattern you describe.您声称示例文件名的前 3 个符合您描述的模式。 I believe that only two do.
我相信只有两个人这样做。
@ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
FOR /f "delims=" %%e IN (
'dir /b /a-d "%sourcedir%\A*.tst"^|findstr /X /I /R "A[0-9][0-9][0-9][0-9]_ZZ[a-z][a-z][a-z]_DT[0-9]_F[0-9].tst" '
) DO ECHO COPY "%sourcedir%\%%e" X:
)
GOTO :EOF
Always verify against a test directory before applying to real data.在应用于真实数据之前,请始终对照测试目录进行验证。
The required COPY commands are merely ECHO
ed for testing purposes.所需的 COPY 命令只是出于测试目的而被
ECHO
编辑。 After you've verified that the commands are correct , change ECHO COPY
to COPY
to actually copy the files.确认命令正确后,将
ECHO COPY
更改为COPY
以实际复制文件。 Append >nul
to suppress report messages (eg. 1 file copied
) Append
>nul
以抑制报告消息(例如1 file copied
)
Simply execute a dir
command that reports only filenames matching the *.tst
mask.只需执行一个
dir
命令,它只报告与*.tst
掩码匹配的文件名。 Filter this list with findstr
which /X
exactly matches the regular expression provided.使用
findstr
过滤此列表,其中/X
与提供的正则表达式完全匹配。 findstr
only has a limited implementation of regular expressions. findstr
仅具有有限的正则表达式实现。 The /I
forces a case-insensitive match. /I
强制进行不区分大小写的匹配。 If you want case-sensitive, remove the /I
and change each [az]
to [a-zA-Z]
(leave as-is if you want lower-case only in these positions.)如果您想要区分大小写,请删除
/I
并将每个[az]
更改为[a-zA-Z]
(如果您只想在这些位置使用小写,请保持原样。)
See findstr /?
见
findstr /?
from the prompt for more documentation, or search for examples on SO.从提示获取更多文档,或在 SO 上搜索示例。
---- revision to cater for multiple filemasks and subdirectories --- ---- 修订以适应多个文件掩码和子目录 ---
@ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "maskfile=%sourcedir%\q74442552.txt"
FOR /f "tokens=1*delims=" %%e IN (
'dir /b/s /a-d "%sourcedir%\*.tst"^|findstr /E /I /R /g:"%maskfile%" '
) DO ECHO COPY "%%e" X:
)
GOTO :EOF
Changes:变化:
maskfile
maskfile
dir
command requires the /s
switch to scan subdirectories dir
命令需要/s
开关来扫描子目录dir
command loses the initial A
dir
命令的文件掩码丢失了初始A
findstr
command replaces the /X
switch with /E
findstr
命令将/X
开关替换为/E
findstr
command loses the regex expression. findstr
命令丢失了正则表达式。 These are transferred to a file and the file is nominated by the /g:
switch./g:
开关指定。copy
command loses the source-directory as the directory will be included in %%e
copy
命令会丢失源目录,因为该目录将包含在%%e
中The file "q74442552.txt" contains lines that are of the form文件“q74442552.txt”包含以下形式的行
A[0-9][0-9][0-9][0-9]_ZZ[a-z][a-z][a-z]_DT[0-9]_F[0-9].tst
A[0-9][0-9][0-9][0-9]_ZZ[a-z][a-z][a-z]_to.*.tst
This time, %%e
acquires the full pathname of the files found.这次,
%%e
获取找到的文件的完整路径名。 Since the filemask ends .tst
, the only filenames to pass the dir
filter will be those that end .tst
.由于文件掩码以
.tst
结尾,因此只有以.tst
结尾的文件名才能通过dir
过滤器。
The /e
switch tells findstr
to match string that E nd with the regex strings in the file specified as /g:
. /e
开关告诉findstr
将E nd 的字符串与指定为/g:
的文件中的正则表达式字符串进行匹配。
The strings in the file must comply with Microsoft's partial regex
implementation, one to a line.文件中的字符串必须符合 Microsoft 的部分
regex
实现,一个到一行。
In summary, findstr
uses as regex
总之,
findstr
用作regex
\
to use it literally\
以按字面意思使用它low-high
low-high
So - you then need to brew-your own using the examples I've supplied.所以 - 然后您需要使用我提供的示例自己酿造。 The second line matches
Axxxx_ZZyyy_to{anything}.tst
for instance.例如,第二行匹配
Axxxx_ZZyyy_to{anything}.tst
。
--- Minor revision to deal with maintaining destination-tree ----- (see notes to final revision for why this doesn't quite work) --- 处理维护目标树的小修改 ----- (请参阅最终修订说明为什么这不太有效)
@ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "maskfile=%sourcedir%\q74442552.txt"
SET "destdir=u:\your results"
FOR /f "tokens=1*delims=" %%e IN (
'dir /b/s /a-d "%sourcedir%\*.tst"^|findstr /E /I /R /g:"%maskfile%" '
) DO ECHO "%%~nxe"&XCOPY /Y /D /S "%sourcedir%\%%~nxe" "%destdir%\">nul
)
GOTO :EOF
This version adds the destination root directory as destdir
.此版本将目标根目录添加为
destdir
。
The dir... findstr...
works as before to list the filenames to copy. dir... findstr...
像以前一样工作以列出要复制的文件名。
The prior version used echo copy
to report the proposed copy operation, but the destination was always the same directory.以前的版本使用
echo copy
来报告建议的复制操作,但目标始终是同一目录。
The replacement XCOPY
line maintains the directory structure at the destination.替换的
XCOPY
行在目的地维护目录结构。
Note: the XCOPY
is "live".注意:
XCOPY
是“实时”的。 The files will be copied to the destination if run as-is.如果按原样运行,文件将被复制到目标位置。 Always verify against a test directory before applying to real data.
在应用于真实数据之前,请始终对照测试目录进行验证。
To "defuse" the XCOPY
, add the /L
switch and remove the >nul
.要“化解”
XCOPY
,请添加/L
开关并删除>nul
。 This will cause XCOPY
to report the source name that would be copied instead of copying
it.这将导致
XCOPY
报告将被复制的源名称而不是copying
它。 (The >nul
suppresses the report) (
>nul
禁止报告)
The /D
only copies source files that eitherr do not exist in the destination of have a later datestamp in the source. /D
仅复制目标中不存在或源中具有较晚日期戳的源文件。
The action is to xcopy
each file name found ( %%~nxe
) from the source directory tree to the destination.该操作是将找到的每个文件名(
%%~nxe
xcopy
从源目录树复制到目标。 Therefore, any file xyz.tst
found anywhere in the source tree will be xcopy
d to the destination tree.因此,在源树中任何位置找到的任何文件
xyz.tst
都将被xcopy
d 到目标树。 The /D
means that once xyz.tst
is encountered on the source tree, it will be skipped should it be encountered again. /D
意味着一旦在源代码树上遇到xyz.tst
,如果再次遇到它,它将被跳过。
--- Final (I hope) revision --- ---最终(我希望)修订---
@ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=U:\Users\tocil\Desktop\aoi"
SET "maskfile=%sourcedir%\q74442552.txt"
SET "destdir=u:\your results"
FOR /f "tokens=1*delims=" %%e IN (
'dir /b/s /a-d "%sourcedir%\*.tst"^|findstr /E /I /R /g:"%maskfile%" '
) DO (
rem drive and path to 'dirname' - has terminal "\"
SET "dirname=%%~dpe"
rem remove the sourcedir from dirname
FOR %%y IN ("%sourcedir%") DO CALL SET "dirname=%%dirname:%%~y=%%"
rem copy or xcopy the file to the destination.
FOR /f "tokens=2delims==" %%y IN ('set dirname') DO XCOPY /Y "%%e" "%destdir%%%y">nul
)
)
GOTO :EOF
Always verify against a test directory before applying to real data.在应用于真实数据之前,请始终对照测试目录进行验证。
Note to self: Only if the filemask provided to XCOPY
is ambiguous (ie. contains ?
or *
) will XCOPY obey the /s
switch unless the target file exists in the starting source directory.自我注意:只有当提供给
XCOPY
的文件掩码不明确(即包含?
或*
)时,XCOPY 才会服从/s
开关,除非目标文件存在于起始源目录中。
hence因此
xcopy /s sourcedir\myfile destdir
will copy myfile
from the entire tree ONLY if sourcedir\myfile
exists.仅当
sourcedir\myfile
存在时,才会从整个树中复制myfile
。
xcopy /s sourcedir\myf?le destdir
will copy myfile
from the entire tree regardless.无论如何都会从整个树中复制
myfile
。 Unfortunately it will also copy myfale
and myfule
as well.不幸的是,它也会复制
myfale
和myfule
。
Hence, the new approach.因此,新方法。
First, perform a dir /b /s
to get all of the filenames and filter as before.首先,执行
dir /b /s
以获取所有文件名并像以前一样进行过滤。 This is being assigned to %%e
.这被分配给
%%e
。
Take the drive and path only of the file and assign to dirname
.仅获取文件的驱动器和路径并分配给
dirname
。
The next step is a little complex.下一步有点复杂。 First, set the value of
%%y
to the name of the source directory.首先,将
%%y
的值设置为源目录的名称。 Next, use a parser trick to remove that name from dirname
.接下来,使用解析器技巧从
dirname
中删除该名称。 The mechanics are: Parse the %%dirname:%%~y=%%
(because the call
causes the set
to be executed in a sub-shell) whuch does the normal left-to-right evaluation.机制是:解析
%%dirname:%%~y=%%
(因为call
导致set
在子 shell 中执行),它执行正常的从左到右的评估。 %%
is an escaped-%, so is replaced by %
; %%
是一个转义的%,所以被替换为%
; %%y
is an active metavariable so is replaced by (the name of the source directory) and the ~
causes the quotes to be stripped from that name. %%y
是一个活动的元变量,因此被替换为(源目录的名称)并且~
导致从该名称中删除引号。 The resultant command executed is thus SET "dirname=%dirname:nameofsourcedirectory=%"
因此,执行的结果命令是
SET "dirname=%dirname:nameofsourcedirectory=%"
So now we can construct a copy
-class instruction.所以现在我们可以构造一个
copy
类指令。 dirname
now contains the relative directory for the destination, which we can extract from the environment by parsing a set
listing (Could also be done with delayed expansion
) where %%y
gets set to the relative directory and has both a leading and trailing backslash, so the destination directory is simply "%destdir%%%y"
. dirname
现在包含目标的相对目录,我们可以通过解析set
列表(也可以通过delayed expansion
来完成)从环境中提取它,其中%%y
被设置为相对目录并且有一个前导和尾随反斜杠,所以目标目录只是"%destdir%%%y"
。 XCOPY
then knows to create that directory if necessary ( %%y
has a trailing backslash) and we know the source filename is in %%e
. XCOPY
然后知道在必要时创建该目录( %%y
有一个尾随反斜杠)并且我们知道源文件名在%%e
中。
You could also use a copy
to do the same thing, but you'd need to create the destination directory first.您也可以使用
copy
来做同样的事情,但您需要先创建目标目录。 Another advantage of XCOPY
is that you can also specify the /d
switch to not copy files that have an earlier date over files that have a later date. XCOPY
的另一个优点是您还可以指定/d
开关以不复制日期较早的文件覆盖日期较晚的文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.