Batch file 将文件名与.bat进行比较并将缺少的条目写入.txt

Batch file 将文件名与.bat进行比较并将缺少的条目写入.txt,batch-file,compare,filenames,Batch File,Compare,Filenames,我想比较文件夹中的一些文件,然后将缺少的文件写入文本文件 我有一个文件夹 c:\sessions\ 里面有文件。这些文件看起来像: Blabla-1111-FOO Blabla-1111-BAR1 Bleble-2222-FOO Bleble-2222-BAR1 Bleble-2222-BAR2 Bleble-2222-BAR3 Bleble-2222-BAR4 Blublu-5678-FOO Blublu-5678-BAR1 Blublu-5678-BAR2 Blublu-5678-BAR3

我想比较文件夹中的一些文件,然后将缺少的文件写入文本文件

我有一个文件夹

c:\sessions\

里面有文件。这些文件看起来像:

Blabla-1111-FOO
Blabla-1111-BAR1
Bleble-2222-FOO
Bleble-2222-BAR1
Bleble-2222-BAR2
Bleble-2222-BAR3
Bleble-2222-BAR4
Blublu-5678-FOO
Blublu-5678-BAR1
Blublu-5678-BAR2
Blublu-5678-BAR3
Blublu-5678-BAR4
Blublu-5678-BAR5
Bleble-6666-FOO
Bloblo-7777-FOO
Bloblo-8888-FOO
Bloblo-9999-FOO
我需要一个.bat文件,该文件将所有以-FOO结尾且不存在匹配-BAR的文件写入noBARs.txt。因此,在本例中,noBARs.txt应该如下所示:

Bleble-6666-FOO
Bloblo-7777-FOO
Bloblo-8888-FOO
Bloblo-9999-FOO
可以有属于一个-FOO文件的多个-BAR文件。
提前感谢各位。

您可以尝试以下方法:

@echo off

setlocal enabledelayedexpansion
set "source=c:\sessions"
set "output=noBARs.txt"
set "find=*foo"
set "repl=bar*"

1>"%output%" (
  for %%e in ("%source%\%find%") do (
    set "file=%%e"
    if not exist "!file:~0,-3!%repl%" (
      echo %%~ne
    )
  )
)
这将遍历文件名中包含
*foo
的所有文件。然后将文件名的最后3个字符替换为
bar*
,并检查文件是否存在。如果相应的
bar
文件不存在,它会将原始文件名写入输出文件
noBARs.txt


我根据dEEkAy的最后一条评论添加了脚本的另一个版本,他在评论中指出,以
FOO
结尾并后跟一个数值常量的文件也应该进行测试。我仍然很不确定dEEkAy的确切意图是什么,但我假设文件名
*FOO*
的处理方式应该与
*FOO
相同

以下输入:

Blabla-1111-FOO
Blabla-1111-BAR1
Bleble-2222-FOO
Bleble-2222-BAR1
Bleble-2222-BAR5
Blublu-3333-FOO6
Blublu-3333-BAR1
Blublu-5678-FOO
Blublu-5678-FOO1
Blublu-5678-BAR2
Blublu-5678-BAR4
Bleble-6666-FOO
Bloblo-7777-FOO5
Bloblo-7777-BAR8
Bloblo-9999-FOO
Blublu-9999-FOO9
Bloblo-!^^!-FOO
将产生以下输出:

Bleble-6666-FOO
Bloblo-!^^!-FOO
Bloblo-9999-FOO
Blublu-9999-FOO9
脚本的替代版本也比原始版本更健壮。它现在应该能够适当地处理包含感叹号和插入符号的文件名和路径。不幸的是,这是有代价的。由于for循环的每次迭代都会执行
call
命令,因此脚本的速度要慢得多。也许有更多批处理文件脚本编写经验的人可以想出更好的解决方案

@echo off

setlocal disabledelayedexpansion
set "source=c:\sessions"
set "output=noBARs.txt"
set "find=foo"
set "repl=bar"

1>"%output%" (
  for %%e in ("%source%\*%find%*") do (
    set "path=%%~dpe"
    set "file=%%~ne"

    setlocal enabledelayedexpansion
    call :ReplaceEndOfString file match "%find%" "%repl%"

    if not exist "!path!!match!*" (
      echo !file!
    )
    endlocal
  )
)
exit /b

:ReplaceEndOfString (__in *source, __out *dest, __in find, __in repl) {
  set "temp=!%1:*%~3=%~3!"
  set "%2=!%1:%temp%=%~4!"
  exit /b
}

请记住,
%source%\*%find%*”
将匹配任何文件名中包含
%find%
,而
%source%\*%find%?“
只匹配以
%find%
结尾的文件名,包括一个可选字符,可以是任何字符。

谢谢我的朋友。你帮我省了很多麻烦。您的解决方案非常有效。我只需将该部分更改为-3!%匹配%to-4因为在我的实际问题中,我得到了一些不同的名称。是否有一种方法可以覆盖输出文件,而不是每次运行此批处理时追加?似乎我无法再编辑我的注释。我通过del删除了文件,解决了追加问题。。。txt@dEEkAy我已经相应地修改了脚本。每次运行时,输出文件都将被覆盖。如果源目录包含很多文件,那么它也会更快。如果我的帖子帮助您解决了问题,请随时将其标记为答案。您的新版本将生成一个包含完整路径和文件名的文本文件。我将坚持使用第一个选项,在输入for块之前删除文件。这个技巧做得很好。是否可以为foo部件输入变量/参数?现在,您的解决方案只是将文件foo的最后一部分替换为bar和checks。在我的实际问题中,有时我有foo1,foo2,这会产生问题。尤其是如果TestTest-1234-foo1和-foo2有与-bar匹配的文件,它仍然会打印出这些文件,就好像它们没有相应的-bar文件一样。@dEEkAy两个版本的脚本都使用命令
echo%%~ne
打印FOO文件的名称。for循环变量
%e
~n
部分指定只应使用文件名,而不应使用完整路径。我不明白这怎么会突然不一样。另一件我不明白的事情是,一个名为
TestTest-1234-FOO1
的文件是如何打印出来的。仅迭代以
*foo
结尾的文件,而不是
*foo*
*foo?
。关于你提到的其他情况,你能用一个新的输入和预期输出列表来更新你的帖子吗?