对于批处理文件中的/r,突然在文件路径中添加句点 [英] For /r in batch file suddenly adding a period to file path

查看:109
本文介绍了对于批处理文件中的/r,突然在文件路径中添加句点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编辑一些批处理文件,这些批处理文件使用doff.exe设置日期变量,然后搜索以该日期命名的文件夹的子文件夹,以查找特定文件,将其复制,重命名,然后对其进行处理.突然之间,在不更改其编写方式的情况下,for/r循环为文件路径添加了一个句点.因此,在使用doff并导航到以日期命名的目录之后,这是我的代码:

I was editing some batch files that use doff.exe to set a date variable, then search through the subfolders of a folder named for the date to find a particular file, copy it, rename it, then process it. All of a sudden, without changing the way it was written, the for /r loop is adding a period to the file path. So, after using doff and navigating to the date-named directory this is my code:

对于(.)中的/r %% d,请确实复制%% d \ FILE.TXT Y:\ Folder \ subfolder \ other_folder \

for /r %%d in (.) do copy %%d\FILE.TXT Y:\Folder\subfolder\other_folder\

它曾经用来输出:

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.

,直到找到文件,然后将其复制.现在,它返回此值(注意文件名前面的额外的.\):

until it found the file, then it would copy it. Now, instead, it returns this (note the extra .\ in front of the filename):

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.

由于文件路径中有多余的.\,因此从未找到该文件.我没有更改任何已知的信息,我们在无数地方使用了此代码字符串,我感觉自己正在服用疯狂药丸.如果相关,那么这里是完整的脚本:

And never finds the file, because of the extra .\ in the file path. I haven't changed anything that I know of, we use this code string in tons of places, I feel like I'm taking crazy pills. In case it's relevant, here's the full script to that point:

for /f "tokens=1-3 delims=/ " %%a in ('doff yyyymmdd') do (
set mm2=%%a
set dd2=%%b
set yyyy2=%%c)

X:
cd Stuff
cd Other_stuff
cd %mm2%

for /r %%d in (.) do copy %%d\FILE.TXT Y:\Folder\subfolder\other_folder\

推荐答案

首先,任何命令通常都不会突然更改其行为而没有更改任何内容.我可以向您保证for不会像这样改变.

First of all, no command usually changes its behaviour all of a sudden without having changed anything. I can assure you for does not change just like that.

此外,文件路径中的其他.完全没有害处,因为.仅表示当前目录.因此,D:\a\b\c.ext指向与D:\a\.\b\.\c.ext相同的目标.
(仅出于完整性考虑,还有..指向父目录,因此它向上一级,因此D:\a\b\c.ext指向与D:\a\b\d\..\c.ext相同的项.)

Furthermore, an additional . in a file path does not harm at all, because . just means the current directory. Therefore D:\a\b\c.ext points to the same target as D:\a\.\b\.\c.ext.
(Just for the sake of completeness, there is also .. which points to the parent directory, so it goes one level up, hence D:\a\b\c.ext points to the same item as D:\a\b\d\..\c.ext.)

无论如何,要了解发生了什么以及多余的.来自何处,您需要知道

Anyway, to understand what is happening and where the extra . comes from, you need to know that the for command (without and with the /R option) does not access the file system always but only when needed.

仅当至少for命令才访问文件系统.集合中使用了诸如*?之类的>通配符(该集合是循环变量引用后的括号之间的部分;键入for /?).您可以轻松地通过在命令提示符窗口中键入以下代码片段来确认(要在批处理文件中使用此代码片段,请将%-符号加倍):

The plain for command accesses the file system only when at least a wildcard like * or ? is used in the set (the set is the part in between the parentheses following the loop variable reference; type for /?). You can easily confirm that with the following code snippet typed into a command prompt window (to use this in a batch file, double the %-signs):

>>> 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循环仅返回现有文件,因此需要访问文件系统.第二个循环仅返回给定的项目,而无需访问文件系统.这两个项目都包含文件名中不允许使用的字符(/),因此不存在此类文件.

The first for loop returns existing files only, so the file system needs to be accessed. The second loop just returns the given items without accessing the file system. Both items contain a character (/) that is not allowed in file names, so there cannot exist such files.

对于for /R的集合(又是()之间的部分),它是完全相同的.但是,要检索递归目录树,当然必须访问文件系统.因此,请查看以下代码段(鉴于当前目录为C:\Test,其中包含3个子目录):

For the set of for /R (that is again the part in between ()) it is exactly the same. However, to retrieve the recursive directory tree, the file system has to be accessed of course. So check out the following code snippet (given the current directory is C:\Test that contains 3 sub-directories):

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

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

As you can see in the first example the file system is accessed and only matching files are returned. In the second example, the directory tree is retrieved from the file system, but the items in the set are just appended and not checked against the file system.

.forfor /R而言没有什么特殊之处,它只是一个没有通配符的字符串,因此不检查文件系统.因此,在我们的测试场景中,输出为:

The . is nothing special to for or for /R, it is just a string without a wildcard, so the files system is not checked. Therefore in our test scenario the output would be:

>>> 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\.

我希望这可以解释您面临的行为!

I hope this explains the behaviour you are facing!

仅出于完整性考虑:
如果出于美观原因要摆脱附加的.,请嵌套另一个(标准)for循环,并使用 ~f修饰符:

Just for the sake of completeness:
If you want to get rid of the appended . for cosmetic reasons, nest another (standard) for loop and use the ~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

这篇关于对于批处理文件中的/r,突然在文件路径中添加句点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆