我正在编辑一些使用doff.exe设置日期变量的批处理文件,然后搜索为日期命名的文件夹的子文件夹以查找特定文件,复制它,重命名,然后处理它。突然,在不改变写入方式的情况下,for / r循环正在向文件路径添加句点。因此,在使用doff并导航到以日期命名的目录后,这是我的代码:
for / r %% d in(。)do copy %% d \ FILE.TXT Y:\ Folder \ subfolder \ other_folder \
以前用它输出:
preg_match()
直到找到该文件,然后才会复制它。现在,它返回它(注意文件名前面的额外。\):
X:\Stuff\other_stuff\20180314>copy X:\Stuff\Other_stuff\20180314\FILE.TXT Y:\Folder\subfolder\other_folder
The system cannot find the file specified.
并且永远不会找到该文件,因为文件路径中有额外的。\。我没有改变我所知道的任何东西,我们在很多地方使用这个代码字符串,我觉得我正在服用疯狂的药片。如果它是相关的,那么这里是完整的脚本:
X:\Stuff\other_stuff\20180314>copy X:\Stuff\Other_stuff\20180314\.\FILE.TXT Y:\Folder\subfolder\other_folder
The system cannot find the file specified.
答案 0 :(得分:1)
首先,没有命令通常会在没有改变任何事情的情况下突然改变其行为。我可以向你保证for
不会像那样改变。
此外,文件路径中的附加.
根本不会造成伤害,因为.
仅表示当前目录。因此D:\a\b\c.ext
指向与D:\a\.\b\.\c.ext
相同的目标
(仅为了完整性,还有..
指向父目录,因此它向上升级,因此D:\a\b\c.ext
指向与D:\a\b\d\..\c.ext
相同的项目。)< / p>
无论如何,要了解正在发生的事情以及额外的.
来自何处,您需要知道for
command(没有和/R
option)无法访问文件系统总是但只在需要的时候。
普通for
命令只有在集合中至少使用wildcard *
或?
时才会访问文件系统(集合介于两者之间)循环变量引用后面的括号;键入for /?
)。您可以通过在命令提示符窗口中键入以下代码段来轻松确认(要在批处理文件中使用此代码,请将%
- 符号加倍):
>>> rem /* List all `*.txt` and `*.bin` files in current directory;
>>> rem the example output below lists two files: */
>>> for %I in (*.txt *.bin) do @echo %I
sample.txt
data.bin
>>> rem // Print all items even if there are no such files:
>>> for %I in (just/text no/file) do @echo %I
just/text
no/file
第一个for
循环仅返回现有文件,因此需要访问文件系统。第二个循环只返回给定的项而不访问文件系统。这两个项目都包含文件名中不允许的字符(/
),因此不存在此类文件。
对于for /R
的集合(也就是()
之间的部分),它完全相同。但是,要检索递归目录树,必须访问文件系统。因此,请查看以下代码段(假设当前目录为C:\Test
,其中包含3个子目录):
>>> rem /* List all `*.txt` and `*.bin` files in current directory tree;
>>> rem the example output below lists some files: */
>>> for /R %I in (*.txt *.bin) do @echo %I
C:\Test\sample.txt
C:\Test\sub1\any.bin
C:\Test\sub1\data.bin
C:\Test\sub2\text.txt
>>> rem // Print all items even if there are no such files:
>>> for /R %I in (just/text no/file) do @echo %I
C:\Test\just/text
C:\Test\no/file
C:\Test\sub1\just/text
C:\Test\sub1\no/file
C:\Test\sub2\just/text
C:\Test\sub2\no/file
C:\Test\sub3\just/text
C:\Test\sub3\no/file
正如您在第一个示例中所看到的,访问文件系统并且仅返回匹配的文件。在第二个示例中,从文件系统中检索目录树,但是只是附加了集合中的项目,而不是对文件系统进行检查。
.
对于for
或for /R
来说并不特别,它只是一个没有通配符的字符串,因此不会检查文件系统。因此,在我们的测试场景中,输出将是:
>>> rem // `.` is the only character in the set:
>>> for /R %I in (.) do @echo %I
C:\Test\.
C:\Test\sub1\.
C:\Test\sub2\.
C:\Test\sub3\.
我希望这能解释你所面临的行为!
仅为了完整性:
如果由于美观原因想要删除附加的.
,请嵌套另一个(标准)for
循环并使用~f
modifier:
>>> rem // `.` is the only character in the set:
>>> for /R %I in (.) do @for &J in (%I) do echo %~fI
C:\Test
C:\Test\sub1
C:\Test\sub2
C:\Test\sub3
答案 1 :(得分:0)
使用FOR /R
时,如果使用单个句点,则会显示始终的结尾时段。如果你想摆脱它,那么这样做:
for /r %%G in (.) do copy %%~fG\FILE.TXT Y:\Folder\subfolder\other_folder\