修复 findstr 以忽略与路径匹配的文件名

Fix findstr to ignore matching filenames with path

我正在尝试创建昨天创建的文件列表。

我在没有 /c:"cmd /c echo @path" 的情况下也能正常工作,但我想要完整路径。

forfiles /s /d -1 /m *.txt /c:"cmd /c echo @path" > a.txt
forfiles /s /m *.txt /c:"cmd /c echo @path" > b.txt
FOR /f "delims=; tokens=*" %%X IN ('findstr /v /g:a.txt b.txt') DO (
    echo %%X
)

解决在包含反斜杠的路径中使用 findstr 的问题的最佳方法是什么?我是否需要将比较文件中的所有反斜杠替换为其他符号,然后再将其更改回来,或者是否有更简单的方法在 findstr 行中执行此操作?

我更喜欢 来完成这样的任务:

Get-ChildItem -Path "C:\Users\tivrick" -Recurse -ErrorAction SilentlyContinue | Where-Object { -Not $_.PSIsContainer -And $_.CreationTime.Date -Eq (Get-Date).Date.AddDays(-1) } | Select-Object -ExpandProperty FullName

如果你真的需要 运行 那来自 :

@PowerShell -NoP "GCI "C:\Users\tivrick" -R -EA SilentlyContinue|?{!$_.PSIsContainer -And $_.CreationTime.Date -Eq (Get-Date).Date.AddDays(-1)}|Select -Exp FullName"

findstr command 检查第一个搜索表达式并在找到 meta-character 时更改为正则表达式模式,否则更改为文字模式,除非您通过 /L 明确预定义模式(文字)或 /R(正则表达式)。

但是 findstr 是一个讨厌的野兽,因为即使 /L 仍然存在一些问题:

  • 多个文字搜索字符串可能会返回错误的结果,除非您指定 /I 进行 case-insensitive 搜索;但这在这里无论如何都不是问题,因为您正在处理目录和文件名,无论如何 case-insensitively 都被 Windows 处理;
  • 虽然在字面量模式下,转义 meta-character 像 .[]^$、[ =22=、*?在前面有\时仍然出现;你可以将所有 \ 加倍来解决这个问题;

所以下面的代码应该适用于大多数情况; delayed expansion is enabled herein by cmd /V,需要读取中间变量FILE,即写入在同一个命令行中读取:

forfiles /S /M "*.txt" /D -1 /C "cmd /C if @isdir==FALSE (set FILE=@path) & cmd /V /C echo(!FILE:\=\!" > "exclude.txt"
forfiles /S /M "*.txt"       /C "cmd /C if @isdir==FALSE echo @path" > "all.txt"
for /F "delims=" %%X in ('findstr /V /L /I /X /G:"exclude.txt" "all.txt"') do (
    echo(%%X
)

我在这里插入了 if @isdir==FALSE 以不匹配名称以 .txt 结尾的目录。我还添加了 /Xfindstr 以便仅匹配整个 lines/paths。

请注意,文字 findstr 搜索字符串的长度限制为 511 个字节(加倍后 \),可以通过文件路径轻松达到。


但是,完全避免 findstr 的不同方法呢?

这是一个 post 我曾经规定退回比 forfiles 相对日期更新的项目:FORFILES date -after- (date calc in cmd file).