我想在文件夹中比较一些文件,然后将丢失的文件写入文本文件中。
我有一个文件夹
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应该看起来像这样:
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
的所有文件。然后,它用bar*
替换文件名的最后3个字符,并检查文件的存在。如果不存在相应的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
脚本的替代版本也比原始版本更强大。现在,它应该能够处理适当的感叹号和载体的文件名和路径。不幸的是,它确实有成本。由于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%
结尾的文件名,其中包括一个可以是任何可能的可选字符。
我碰巧需要一些与此类似的代码,然后决定再看一下。代码的主要瓶颈似乎是call
命令的调用。虽然我看不到这一点(使用宏除外(,但call
命令的执行时间可以得到很大改进(大约为2倍(。
通过其标签调用功能似乎比调用set
命令要慢得多。我不确定,但是由于需要重新启动整个脚本文件,我可以记住有关呼叫标签速度慢的一些东西。文件名中的脑袋和感叹号似乎也保持不变,因为延迟的扩展阶段似乎发生在set
命令之前。
@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
set "end=!file:*%find%=%find%!"
call set "match=%%file:!end!=%repl%%%"
if not exist "!path!!match!*" (
echo !file!
)
endlocal
)
)
exit /b