【问题标题】:Bat file to list files, using semicolon delimiter?Bat文件列出文件,使用分号分隔符?
【发布时间】:2022-01-09 00:56:30
【问题描述】:

到目前为止,我有这个:

@ECHO OFF

dir *.txt /c /b /on > content.txt

提供输出:

file1.txt
file2.txt
file3.txt

但我需要这样,每行用分号隔开:

file1.txt;
file2.txt;
file3.txt;

我假设我可能需要编写 for 循环并添加字符串“;”某处,但我不知道在哪里或如何做到这一点。或者有没有办法只设置一个特定的分隔符?

编辑:

我的用例发生了变化,我认为如果在子文件夹中也列出文件会更好,但是“/”应该替换为空格“”。

示例输出:

file1.txt;
file2.txt;
subfolder1 file1.txt;
subfolder2 file1.txt;

请注意,我不想要完整的父路径,只想要子文件夹。

【问题讨论】:

  • 打开命令提示符窗口,键入dir /? 并按[ENTER] 键以阅读其帮助和使用信息。您会注意到/c 选项对您毫无用处!然后请输入for /? 并按下[ENTER] 键以了解如何使用for 循环。我已经提供了一个答案,它应该可以实现您的目标,使用该信息,并以最有效和最可靠的方式这样做。

标签: string windows batch-file cmd directory


【解决方案1】:

快速单行回答:

@(For /F Tokens^=*^ Delims^=^ EOL^= %%G In ('Dir "*.txt" /A:-D /B /O:N 2^>NUL') Do @Echo %%G;) 1>"content.log"

…在:

(For /F Tokens^=*^ Delims^=^ EOL^= %G In ('Dir "*.txt" /A:-D /B /O:N 2^>NUL') Do @Echo %G;) 1>"content.log"

我决定输出到一个.log 文件,这样列表就不会包含它自己。

请使用内置帮助了解每个命令的工作原理。

当您阅读帮助信息时,请注意“简单”for 循环不会拾取所有文件,例如它会忽略所有隐藏文件。此外,尽管您可能从测试中获得任何第一印象,但返回文件的顺序取决于文件系统和类型。 dir 命令是确保排序顺序的最有效方式。


[编辑/]

这是一个 解决方案,(因为这是您发布的答案),用于您的全新且完全不同的问题

@(For /F Tokens^=*^ Delims^=^ EOL^= %%G In ('Dir "*.txt" /A:-D /B /O:N /S 2^>NUL') Do @(Set "FileName=%%~dpG" & SetLocal EnableDelayedExpansion & Set "Filename=!FileName:~,-1!" & For %%H In ("!FileName:%__CD__%=!") Do @EndLocal & Echo %%~H %%~nxG;)) 1>"content.log"

将来,当您对所提出的问题已有答案时,不要更改该问题,因为不仅主要命令不同,而且预期的结果格式也不同。

【讨论】:

  • Tokens=* 在指定 delims= 时不是必需的。如果不是绝对必要的话,我不会对for /F 使用未加引号且难以理解的语法,这里不是这种情况(eof 很容易被eof=| 停用,因为| 不能出现在文件名中)…
  • @aschipfl 可能没有必要,但显然两者都使用比单独使用 delims 更快。这是不久前在 DosTips 上发现的。随意搜索它,(我相信 Mofi 在一周左右之前做过,当时他们对我对两者的使用做出了相同的评论,后来证实这是真的。)。我确实声明我发布了最有效和最强大的方法,因此将其包括在内,因为速度与效率成正比
  • 嗯……我很确定记得 DosTips 上的一篇相反的帖子(但我没记错的话,是用户 npocmaka 的一篇旧帖子)。无论如何,使用这两个选项当然没有错,我现在认为这是一个品味问题。我一定会很快在 DosTips 上查找 Mofi 的帖子……
  • @aschipfl,我认为 Mofi 的 cmets 可能低于this post,并且他们已经清理了它们。恐怕您可能需要与 Mofi 核实,以获得确认,或者甚至是 Mofi 和我读过的信息,(我认为是 jeb),随后是否已被什么取代你读过 npocmaka。
  • @TaaviViikman,在命令提示符窗口中输入dir /? 并读取输出使用信息;你会发现/A 过滤属性,那个属性D 表示Directory,前面的- 反转过滤器,所以-D 表示NOT a Directory i>,只返回文件
【解决方案2】:

一个简单的for 循环就可以了:

@(for %%i in (*.txt) do @echo %%i;)>"content.txt"

但是,如果 contents.txt 存在,它也会将其内容回显给自身,因此您可以将其排除。

@(for %%i in (*.txt) do @if /i not "%%~i" == "content.txt" @echo %%i;)>"content.txt"

如果计划还要遍历子目录,请运行 for /R

【讨论】:

  • 需要说明的是,返回文件的顺序取决于这里的文件系统,而dir /B /O:N(问题中使用的)则不...
  • 100% 正确,@aschipfl,但默认排序顺序是文件名,除非 OP 需要不同的排序顺序,这将使我的答案无效。
  • 在 NTFS 上,排序顺序是按名称(尽管处理扩展字符的方式与 dir /O:N 不同)。在 FAT 上,项目基本上按创建日期/时间排序。现在取决于提问者他们需要什么……
  • @aschipfl,是的,但是胖子成为 FS 的几率不是那么……胖子? :D
  • 除非您更改我的代码,否则这是不可能的。
【解决方案3】:

我找到了列出子文件夹的部分解决方案,不包括父路径。它并不完美(如上面 cmets 所述,for 循环并不准确,我对 pushd 命令也不满意),但可以。我用“空格”代替了\,因为我需要它。

@echo off
setlocal enabledelayedexpansion
pushd "c:\users\documents\"
(
  for /r %%a in (*.txt) do (
    set x=%%a
    set x=!x:%cd%=!;
    echo !x:\= !
  )
)>filelist.log
popd

代码说明:

首先我删除带有set x=!x:%cd%=!; 的父路径(感叹号替换%,请参阅enabledelayedexpansion 帮助),然后在回显时删除斜杠。

【讨论】:

  • 请注意,正如我在您提交之前为您提供的答案中已经暗示的那样,For /R 循环不会检索所有文件,(具有某些属性的文件被忽略).
  • 我预测你会遇到包含常见嫌疑人的目录名的问题——尤其是=。此外,对于结果 one two three four.txt,可能会报告名为 one two three four.txtone two\three four.txtone two three\four.txtone\two\three\four.txt 的文件(以及其他可能性)。你建议如何区分它们。
  • 我的用例必须忽略带空格的文件名。我有一个单独的批处理脚本,可以从文件名中删除空格。我没有将它包含在这批中,因为:1)增加了批量; 2)我不知道怎么做。否则我不知道答案的好问题。 -= 是问题,是的,我只是没有这样的文件夹名称,无论如何它都是针对特定应用程序的。否则解决方案会很棒。我可能会完全忽略这一点,并制作一个指向文件的不同结构化文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 2019-01-27
  • 1970-01-01
  • 2019-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多