Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 为什么要在批处理程序的FOR循环中创建一个额外的文件?_Shell_Batch File_For Loop_Createfile - Fatal编程技术网

Shell 为什么要在批处理程序的FOR循环中创建一个额外的文件?

Shell 为什么要在批处理程序的FOR循环中创建一个额外的文件?,shell,batch-file,for-loop,createfile,Shell,Batch File,For Loop,Createfile,我编写了以下批处理文件,以使用FOR循环创建多个文件: @echo off cls FOR /L %%i IN (1 1 10) DO ( echo.> file%%i.txt IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'. ) dir /b *.txt FOR %%i IN (*.txt) DO ( echo.> file%%i.txt IF ERRORL

我编写了以下批处理文件,以使用FOR循环创建多个文件:

@echo off cls FOR /L %%i IN (1 1 10) DO ( echo.> file%%i.txt IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'. ) dir /b *.txt FOR %%i IN (*.txt) DO ( echo.> file%%i.txt IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'. ) @回音 cls 对于(110)DO中的/L%%i( echo.>文件%%i.txt 如果ERRORLEVEL 0 echo成功创建了文件“file%%i.txt”。 ) dir/b*.txt 对于(*.txt)中的%%i,请执行以下操作( echo.>文件%%i.txt 如果ERRORLEVEL 0 echo成功创建了文件“file%%i.txt”。 ) 这里,在第一个FOR循环中创建了10个文件(即
file1.txt
file10.txt
) 在第二个FOR循环中,我使用这些文件来构建下一个新文件的名称。(即
filefile1.txt.txt
filefile10.txt.txt

但是,正在创建一个额外的文件:
file1.txt.txt.txt


是什么逻辑问题导致创建了这个额外的文件?

我不知道为什么,但是当您编写
。。。在(*.txt).
for循环的第二个
中,它试图查找在循环体中刚刚创建的文件

为了消除这一点,我将使我的过滤器更具体一点

FOR %%i IN (file??.txt) DO (

我运行了这个,它只创建了预期的20个文件。

正如adarshr所说,第二个FOR循环甚至可以找到新创建的文件。
您可以通过在命令中使用FOR/F来避免这种情况,因为dir的结果在执行循环体之前被完全获取

...
FOR /F "delims=" %%i IN ('dir /b *.txt') DO (  
    echo.> file%%i.txt
    IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'.  
)

编辑-似乎我没有正确地解释它,人们也看不到它是如何工作的。是我的错。我要试着更好地解释它

原因是for命令在内部的工作方式

当到达(文件)
中var的
行时,将检查目录以查看是否有任何文件匹配并需要处理

然后,
for
命令(cmd-really)发出目录查询以枚举文件。此查询仅返回集合中的第一个文件。如果有任何与
for
命令中的文件掩码匹配的传统文件,将设置一个标志,向调用者(cmd)指示有更多文件要处理,但尚未检索剩余文件的列表

内部代码的执行到达迭代的末尾,并且有待读取的文件时,将发送一个查询,以获取待处理文件列表中与
文件选择匹配的剩余

系统用剩余的文件列表填充缓冲区。如果此时文件列表足够短,可以在缓冲区中完全读取,则不会重复查询。如果文件列表太大,无法放入缓冲区,将检索部分列表,并且在处理检索到的列表中的文件时,将再次发送查询以获取更多要处理的文件

缓冲区中的文件数取决于文件名的长度。文件名越短,缓冲区中的文件越多,对文件系统的查询越少

此行为(在第一次文件处理结束时检索剩余的文件列表)仅在文件查询返回有挂起的文件时执行。当一个查询不返回该标志时,将不会检索更多的文件

例外情况

如果在NTFS中工作,则仅当文件的字母顺序大于在
for
命令中处理的最后一个文件时,这些文件才会包含在“重新查询”中

如果FAT有效,则查询将包括生成的所有新文件,这些文件与命令文件选择相匹配,与文件名无关。是的,它可以进入一个无限循环。(在测试中,系统缓冲区仅检索一个文件名,并在每次迭代中重新查询)。你可以试试

break > a.txt && cmd /v:on /c "for %f in (*.txt) do break > !random!.txt"
我的所有测试都是在windows 7 64位、NTFS和FAT32分区(这是在USB驱动器上)上进行的。无法测试其他配置。如果有人看到不同的行为,请发表评论


有关详细信息,请参见,

在(*.txt)do(echo%%i)中为%%i执行
操作时,打印什么内容?只有10个条目或11个条目?如果我在(*.txt)中对%%I执行
(echo%%I)
,当然,我会得到在第一个循环中刚刚创建的文件列表;这与我收到的对
dir*.txt
的回复相同。
/F“delims=“
工作正常,但额外文件的神秘性尚未解决@Satyendra不,正如adarshr所说,您创建的文件也可以通过您的搜索模式找到。如果您在第二个循环中更改扩展名,它不会导致任何问题。我似乎在您的解释中看到,只有一个文件将被多次处理,但我相当肯定,在过去的测试中,有多个文件被多次处理。我误解了你的文字吗?不,没有文件是经过多重处理的。如果在for命令的第一个循环中生成新文件,并且这些文件与for中的集合表达式匹配,则将包括这些文件,因为要处理的完整列表在第一个循环完成之前不会被检索,并且此时会有与集合表达式匹配的新文件。我的理解是,在for循环的开始处,会枚举文件:但会返回第一个文件和具有更多文件标志。稍后,在for循环结束时,再次检索挂起的文件:此时已经创建了一组新文件。那么为什么它不考虑所有这些新创建的文件呢?这将最终进入创建文件的无限循环!!当
for
命令启动时,将进行目录查询,查看是否有要处理的文件,并检索第一个文件名。
for
中的指令块将针对第一个文件运行。一旦第一个文件的处理结束,并且只有在那个时候,只有一次,并且只有在最初有多个文件要处理时,才会进行查询以检索文件列表的剩余部分。如果在处理第一个文件时,生成的文件与
文件选择的
匹配,则这些文件将包含在列表中并进行处理。如果在NT中工作