修复 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 行中执行此操作?
我更喜欢 powershell 来完成这样的任务:
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
如果你真的需要 运行 那来自 batch-file:
@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
结尾的目录。我还添加了 /X
到 findstr
以便仅匹配整个 lines/paths。
请注意,文字 findstr
搜索字符串的长度限制为 511 个字节(加倍后 \
),可以通过文件路径轻松达到。
但是,完全避免 findstr
的不同方法呢?
这是一个 post 我曾经规定退回比 forfiles
相对日期更新的项目:FORFILES date -after- (date calc in cmd file).
我正在尝试创建昨天创建的文件列表。
我在没有 /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 行中执行此操作?
我更喜欢 powershell 来完成这样的任务:
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
如果你真的需要 运行 那来自 batch-file:
@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
结尾的目录。我还添加了 /X
到 findstr
以便仅匹配整个 lines/paths。
请注意,文字 findstr
搜索字符串的长度限制为 511 个字节(加倍后 \
),可以通过文件路径轻松达到。
但是,完全避免 findstr
的不同方法呢?
这是一个 post 我曾经规定退回比 forfiles
相对日期更新的项目:FORFILES date -after- (date calc in cmd file).