对于批处理文件中的/ r,突然向文件路径添加句点

时间:2018-03-14 19:27:06

标签: batch-file

我正在编辑一些使用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.

2 个答案:

答案 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

正如您在第一个示例中所看到的,访问文件系统并且仅返回匹配的文件。在第二个示例中,从文件系统中检索目录树,但是只是附加了集合中的项目,而不是对文件系统进行检查。

.对于forfor /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\