windows 命令提示符/powershell 中的 Globbing 模式
Globbing patterns in windows command prompt/ powershell
我想知道是否有任何方法可以在 windows 上实现此行为,例如:
/b?n/ca? /etc/pa??wd -> 执行 'cat /etc/passwd'
在 PowerShell 中,您可以使用 Resolve-Path,它 解析路径中的通配符,并显示路径内容。
示例:我想从通常驻留在“c:\Program Files (x86)\Windows Kits\bin.0.19041 中的 Windows SDK 中找到 signtool.exe .0\x64\signtool.exe”,其中可能安装了任何其他版本。
所以我可以使用:Resolve-Path 'c:\program*\Windows Kits\bin\*\x64\signtool.exe'
编辑:
如果你想直接执行它,你可以使用 &
调用运算符,例如
&(Resolve-Path 'c:\wind?ws\n?tepad.exe')
除了 PowerShell 中的有限例外,Windows 无 支持 shell-level globbing - 目标命令必须执行它们自己的通配符模式解析 以匹配文件名;如果他们不这样做,则必须 手动 执行 globbing,并将结果作为文字路径传递;有关背景信息,请参阅底部。
PowerShell:
也许令人惊讶的是,您可以通过通配符模式调用可执行文件,正如zett42指出的那样,尽管 该行为存在问题(见底部部分):
# Surprisingly DOES find C:\Windows\System32\attrib.exe
# and invokes it.
C:\Windows\System3?\attr*.exe /?
- 通常,您可以通过
Get-Command
cmdlet 发现命令,包括外部程序。
PowerShell 中的许多 file-processing cmdlet do 执行它们自己的 globbing(例如,Get-ChildItem
、Remove-Item
);如果您正在调用不执行的命令,特别是不执行的外部程序,则必须执行通配 手动 ,预先 ,Unix 除外 调用外部程序时类似平台,其中 PowerShell 确实 执行自动通配(见底部):
使用 Convert-Path
获取匹配文件或目录的完整 file-system-native 路径。
- 虽然
Resolve-Path
也可以工作,但它 returns 对象 您需要访问其 .ProviderPath
属性 才能获得相同的信息(将这些对象字符串化,当您将它们传递给外部程序时隐式发生,产生它们的 .Path
属性,这可能基于 PowerShell-only 驱动外部程序和 .NET API 对此一无所知。)
为了更好地控制匹配的内容,请使用 Get-ChildItem
并根据需要访问结果对象的 .Name
或 .FullName
属性;例如,Get-ChildItem
允许您将匹配限制为 文件 (-File
) 或 目录 (-Directory
) 而已。
PowerShell 可以轻松地以编程方式使用手动执行的通配结果;以下示例将当前目录中所有 *.txt
文件的完整路径作为单独的参数传递给 cmd.exe
的 echo
命令;如果需要,PowerShell 会自动用 "..."
中的空格括起路径:
cmd /c echo (Get-ChildItem -Filter *.txt).FullName
一般来说,请注意 PowerShell 的 wildcard patterns 比主机平台的 file-system API 更强大,并且特别包括对字符集的支持(例如 [ab]
) 和范围(例如 [0-9]
);另一个重要区别是 ?
只匹配 一个 字符,而 Windows 上的原生 file-system API 匹配 none 或一个.
- 但是,当使用 file-processing cmdlet 的
-Filter
参数(例如 Get-ChildItem
)时,会使用 主机平台的 模式,即 -同时限制功能 - 提高性能;一个警告是,在 Unix-like 平台上 ?
然后看起来像在 Windows 上一样,即导致它匹配 none 或一个 字符.
cmd.exe
(命令提示符,遗留 shell):
cmd.exe
不 支持通过通配符模式调用 executables; 一些 cmd.exe
的内部命令(例如,dir
和 del
)和 一些 标准外部程序(例如,attrib.exe
)do 执行它们自己的 globbing;否则你必须手动 ,预先 :
where.exe
,用于发现外部程序的外部程序基本上只支持可执行文件names中的通配符模式(例如where find*.exe
),不在 路径 中,这限制 wildcard-based 查找位于 PATH
环境变量中列出的目录中的可执行文件。
:: OK - "*" is part of a *name* only
where.exe find*.exe
:: !! FAILS: "*" or "?" must not be part of a *path*
:: !! -> "ERROR: Invalid pattern is specified in "path:pattern"."
where.exe C:\Windows\System32\find*.exe
通配符 dir
似乎仅限于 last 路径组件中的通配符:
:: OK - "*" is only in the *last* path component.
dir C:\Windows\System32\attri*
:: !! FAILS: "*" or "?" must not occur in *non-terminal* components.
:: !! -> "The filename, directory name, or volume label syntax is incorrect."
dir C:\Windows\System3?\attri*
以编程方式使用手动通配结果在cmd.exe
[中非常麻烦 并且需要使用 for
语句(其通配符匹配与 dir
命令具有相同的限制);例如,使用 批处理文件 (.cmd
或 .bat
文件)的语法:
使用解析后的可执行文件路径进行调用(假设只有一个个文件匹配):
@echo off
setlocal
:: Use a `for` loop over a wildcard pattern to enumerate
:: the matching filenames - assumed to be just *one* in this case,
:: namely attrib.exe, and save it in a variable.
for %%f in (C:\Windows\System32\attr*.exe) do set "Exe=%%f"
:: Execute the resolved filename to show its command-line help.
"%Exe%" /?
要将匹配的文件名作为多个参数传递给单个命令:
@echo off
setlocal enableDelayedExpansion
:: Use a `for` loop over a wildcard pattern to enumerate
:: matching filenames and collect them in a single variable.
set files=
for %%f in (*.txt) do set files=!files! "%%f"
:: Pass all matching filenames to `echo` in this example.
echo %files%
背景资料:
在Unix类平台上,POSIX-compatibleshell如Bash他们自己执行globbin(将文件名通配符模式解析为匹配的文件名),在 之前目标命令看到生成的文件名,作为名为 [=79= 的功能集的一部分](link 是 Bash 手册)。
在 Windows、cmd.exe
(遗留 shell也称为命令提示符)不执行此类扩展,而 PowerShell 大部分 不.
也就是说,通常每个目标命令解释通配符模式并解析它们匹配文件名。
也就是说,在 PowerShell 中,许多 built-in 命令,称为 cmdlets,do 支持PowerShell 的 wildcard patterns,特别是通过 provider cmdlet 的 -Path
参数,例如 Get-ChildItem
.
此外,更普遍的是,表示 names 的 cmdlet 参数通常也支持通配符;例如,Get-Process exp*
列出映像名称以 exp
开头的所有进程,例如 explorer
.
请注意 Unix-style shell 对 Windows 的扩展也意味着 没有 语义区分在 unquoted 和 quoted 参数之间(例如,*.txt
与 "*.txt"
):目标命令通常会看到 两者作为逐字*.txt
.
在 PowerShell 中,在这些 有限的情况下 会发生自动通配 ]:
也许令人惊讶的是,一个可执行文件文件路径可以通过通配符模式:
as-is,如果模式未包含在 '...'
或 "..."
中 and/or 不包含变量引用或表达式;例如:
C:\Windows\System3?\attri?.exe
通过&
,call operator,否则;例如:
& $env:SystemRoot\System32\attri?.exe
但是,此功能的实用性值得怀疑 - 您什么时候不想预先知道什么特定的 您正在调用的可执行文件? - 鉴于其他上下文中不适当的通配符处理表面也存在,目前尚不清楚它是否 通过设计 实现 - 参见 GitHub issue #4726。
此外,至少在 PowerShell 7.2.4 之前,如果 两个或更多 可执行文件匹配通配符模式,则会出现误导性错误,提示 未找到 匹配的可执行文件 - 请参阅 GitHub 问题 #17468;问题的一个变体也会影响传递 wildcard-based path(与仅仅 name 相对)匹配多个可执行文件到 Get-Command
.
在POSIX-compatibleshells中,multi-match场景处理不同,但同样没用:第一个 匹配的可执行文件被调用,所有其他的都被传递 作为它的参数.
仅在 Unix-like 平台上,PowerShell 模拟 POSIX-compatible shells 调用外部程序时,努力表现得更像platform-native shells;如果 PowerShell 不这样做,那么像 ls *.txt
这样简单的事情就会失败,因为外部 /bin/ls
实用程序随后会收到 verbatim *.txt
作为它的论点。
- 但是,从 PowerShell 7.2.4 开始,此 模拟具有局限性 :
- 无法使用包含 空格 的通配符模式 - 请参阅 GitHub issue #10683。
- 无法包含 隐藏的 文件 - 请参阅 GitHub issue #4683。
- 一静experimental feature, available in preview versions of 7.3,
PSNativePSPathResolution
, automatically translates wildcard patterns based on PowerShell-only drives to their underlying native file-system paths; however, this feature is currently overzealous - see GitHub issue #13640 - and inherently bears the risk of false positives - see GitHub issue #13644
我想知道是否有任何方法可以在 windows 上实现此行为,例如:
/b?n/ca? /etc/pa??wd -> 执行 'cat /etc/passwd'
在 PowerShell 中,您可以使用 Resolve-Path,它 解析路径中的通配符,并显示路径内容。
示例:我想从通常驻留在“c:\Program Files (x86)\Windows Kits\bin.0.19041 中的 Windows SDK 中找到 signtool.exe .0\x64\signtool.exe”,其中可能安装了任何其他版本。
所以我可以使用:Resolve-Path 'c:\program*\Windows Kits\bin\*\x64\signtool.exe'
编辑:
如果你想直接执行它,你可以使用 &
调用运算符,例如
&(Resolve-Path 'c:\wind?ws\n?tepad.exe')
除了 PowerShell 中的有限例外,Windows 无 支持 shell-level globbing - 目标命令必须执行它们自己的通配符模式解析 以匹配文件名;如果他们不这样做,则必须 手动 执行 globbing,并将结果作为文字路径传递;有关背景信息,请参阅底部。
PowerShell:
也许令人惊讶的是,您可以通过通配符模式调用可执行文件,正如zett42指出的那样,尽管 该行为存在问题(见底部部分):
# Surprisingly DOES find C:\Windows\System32\attrib.exe # and invokes it. C:\Windows\System3?\attr*.exe /?
- 通常,您可以通过
Get-Command
cmdlet 发现命令,包括外部程序。
- 通常,您可以通过
PowerShell 中的许多 file-processing cmdlet do 执行它们自己的 globbing(例如,
Get-ChildItem
、Remove-Item
);如果您正在调用不执行的命令,特别是不执行的外部程序,则必须执行通配 手动 ,预先 ,Unix 除外 调用外部程序时类似平台,其中 PowerShell 确实 执行自动通配(见底部):使用
Convert-Path
获取匹配文件或目录的完整 file-system-native 路径。- 虽然
Resolve-Path
也可以工作,但它 returns 对象 您需要访问其.ProviderPath
属性 才能获得相同的信息(将这些对象字符串化,当您将它们传递给外部程序时隐式发生,产生它们的.Path
属性,这可能基于 PowerShell-only 驱动外部程序和 .NET API 对此一无所知。)
- 虽然
为了更好地控制匹配的内容,请使用
Get-ChildItem
并根据需要访问结果对象的.Name
或.FullName
属性;例如,Get-ChildItem
允许您将匹配限制为 文件 (-File
) 或 目录 (-Directory
) 而已。PowerShell 可以轻松地以编程方式使用手动执行的通配结果;以下示例将当前目录中所有
*.txt
文件的完整路径作为单独的参数传递给cmd.exe
的echo
命令;如果需要,PowerShell 会自动用"..."
中的空格括起路径:cmd /c echo (Get-ChildItem -Filter *.txt).FullName
一般来说,请注意 PowerShell 的 wildcard patterns 比主机平台的 file-system API 更强大,并且特别包括对字符集的支持(例如
[ab]
) 和范围(例如[0-9]
);另一个重要区别是?
只匹配 一个 字符,而 Windows 上的原生 file-system API 匹配 none 或一个.- 但是,当使用 file-processing cmdlet 的
-Filter
参数(例如Get-ChildItem
)时,会使用 主机平台的 模式,即 -同时限制功能 - 提高性能;一个警告是,在 Unix-like 平台上?
然后看起来像在 Windows 上一样,即导致它匹配 none 或一个 字符.
- 但是,当使用 file-processing cmdlet 的
cmd.exe
(命令提示符,遗留 shell):cmd.exe
不 支持通过通配符模式调用 executables; 一些cmd.exe
的内部命令(例如,dir
和del
)和 一些 标准外部程序(例如,attrib.exe
)do 执行它们自己的 globbing;否则你必须手动 ,预先 :where.exe
,用于发现外部程序的外部程序基本上只支持可执行文件names中的通配符模式(例如where find*.exe
),不在 路径 中,这限制 wildcard-based 查找位于PATH
环境变量中列出的目录中的可执行文件。:: OK - "*" is part of a *name* only where.exe find*.exe :: !! FAILS: "*" or "?" must not be part of a *path* :: !! -> "ERROR: Invalid pattern is specified in "path:pattern"." where.exe C:\Windows\System32\find*.exe
通配符
dir
似乎仅限于 last 路径组件中的通配符::: OK - "*" is only in the *last* path component. dir C:\Windows\System32\attri* :: !! FAILS: "*" or "?" must not occur in *non-terminal* components. :: !! -> "The filename, directory name, or volume label syntax is incorrect." dir C:\Windows\System3?\attri*
以编程方式使用手动通配结果在
cmd.exe
[中非常麻烦 并且需要使用for
语句(其通配符匹配与dir
命令具有相同的限制);例如,使用 批处理文件 (.cmd
或.bat
文件)的语法:使用解析后的可执行文件路径进行调用(假设只有一个个文件匹配):
@echo off setlocal :: Use a `for` loop over a wildcard pattern to enumerate :: the matching filenames - assumed to be just *one* in this case, :: namely attrib.exe, and save it in a variable. for %%f in (C:\Windows\System32\attr*.exe) do set "Exe=%%f" :: Execute the resolved filename to show its command-line help. "%Exe%" /?
要将匹配的文件名作为多个参数传递给单个命令:
@echo off setlocal enableDelayedExpansion :: Use a `for` loop over a wildcard pattern to enumerate :: matching filenames and collect them in a single variable. set files= for %%f in (*.txt) do set files=!files! "%%f" :: Pass all matching filenames to `echo` in this example. echo %files%
背景资料:
在Unix类平台上,POSIX-compatibleshell如Bash他们自己执行globbin(将文件名通配符模式解析为匹配的文件名),在 之前目标命令看到生成的文件名,作为名为 [=79= 的功能集的一部分](link 是 Bash 手册)。
在 Windows、
cmd.exe
(遗留 shell也称为命令提示符)不执行此类扩展,而 PowerShell 大部分 不.也就是说,通常每个目标命令解释通配符模式并解析它们匹配文件名。
也就是说,在 PowerShell 中,许多 built-in 命令,称为 cmdlets,do 支持PowerShell 的 wildcard patterns,特别是通过 provider cmdlet 的
-Path
参数,例如Get-ChildItem
.此外,更普遍的是,表示 names 的 cmdlet 参数通常也支持通配符;例如,
Get-Process exp*
列出映像名称以exp
开头的所有进程,例如explorer
.请注意 Unix-style shell 对 Windows 的扩展也意味着 没有 语义区分在 unquoted 和 quoted 参数之间(例如,
*.txt
与"*.txt"
):目标命令通常会看到 两者作为逐字*.txt
.
在 PowerShell 中,在这些 有限的情况下 会发生自动通配 ]:
也许令人惊讶的是,一个可执行文件文件路径可以通过通配符模式:
as-is,如果模式未包含在
'...'
或"..."
中 and/or 不包含变量引用或表达式;例如:C:\Windows\System3?\attri?.exe
通过
&
,call operator,否则;例如:& $env:SystemRoot\System32\attri?.exe
但是,此功能的实用性值得怀疑 - 您什么时候不想预先知道什么特定的 您正在调用的可执行文件? - 鉴于其他上下文中不适当的通配符处理表面也存在,目前尚不清楚它是否 通过设计 实现 - 参见 GitHub issue #4726。
此外,至少在 PowerShell 7.2.4 之前,如果 两个或更多 可执行文件匹配通配符模式,则会出现误导性错误,提示 未找到 匹配的可执行文件 - 请参阅 GitHub 问题 #17468;问题的一个变体也会影响传递 wildcard-based path(与仅仅 name 相对)匹配多个可执行文件到
Get-Command
.在POSIX-compatibleshells中,multi-match场景处理不同,但同样没用:第一个 匹配的可执行文件被调用,所有其他的都被传递 作为它的参数.
仅在 Unix-like 平台上,PowerShell 模拟 POSIX-compatible shells 调用外部程序时,努力表现得更像platform-native shells;如果 PowerShell 不这样做,那么像
ls *.txt
这样简单的事情就会失败,因为外部/bin/ls
实用程序随后会收到 verbatim*.txt
作为它的论点。- 但是,从 PowerShell 7.2.4 开始,此 模拟具有局限性 :
- 无法使用包含 空格 的通配符模式 - 请参阅 GitHub issue #10683。
- 无法包含 隐藏的 文件 - 请参阅 GitHub issue #4683。
- 一静experimental feature, available in preview versions of 7.3,
PSNativePSPathResolution
, automatically translates wildcard patterns based on PowerShell-only drives to their underlying native file-system paths; however, this feature is currently overzealous - see GitHub issue #13640 - and inherently bears the risk of false positives - see GitHub issue #13644
- 但是,从 PowerShell 7.2.4 开始,此 模拟具有局限性 :