I would like to know if there is any way to achieve this behavior on windows, for example:
/b?n/ca? /etc/pa??wd -> executes 'cat /etc/passwd'
In PowerShell you can use Resolve-Path which Resolves the wildcard characters in a path, and displays the path contents.
Example: I want to locate signtool.exe from the Windows SDK which typically resides in "c:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" where there could be any other version(s) installed.
So I could use: Resolve-Path 'c:\program*\Windows Kits\10\bin\*\x64\signtool.exe'
EDIT:
If you want to execute it directly you can use the &
invocation operator eg
&(Resolve-Path 'c:\wind?ws\n?tepad.exe')
With limited exceptions in PowerShell, on Windows there is no support for shell-level globbing - target commands must perform their own resolution of wildcard patterns to matching filenames; if they don't, globbing must be performed manually and the results passed as literal paths; see the bottom section for background information.
PowerShell :
Perhaps surprisingly, you can invoke an executable by wildcard pattern, as zett42 points out, though that behavior is problematic (see bottom section):
# Surprisingly DOES find C:\Windows\System32\attrib.exe # and invokes it. C:\Windows\System3?\attr*.exe /?
Get-Command
cmdlet. Many file-processing cmdlets in PowerShell do perform their own globbing (eg, Get-ChildItem
, Remove-Item
); if you're calling commands that do not, notably external programs that don't, you must perform globbing manually , up front , except on Unix -like platforms when calling _external programs, where PowerShell does perform automatic globbbing (see bottom section):
Use Convert-Path
to get the full, file-system-native paths of matching files or directories.
Resolve-Path
may work too, it returns objects whose .ProviderPath
property you need to access to get the same information ( stringifying these objects, as happens implicitly when you pass them to external programs, yields their .Path
property, which may be based on PowerShell-only drives that external programs and .NET APIs know nothing about.) For more control over what is matched, use Get-ChildItem
and access the result objects' .Name
or .FullName
property, as needed; for instance, Get-ChildItem
allows you to limit matching to files ( -File
) or directories ( -Directory
) only.
PowerShell makes it easy to use the results of manually performed globbing programmatically ; the following example passes the full paths of all *.txt
files in the current directory to the cmd.exe
's echo
command as individual arguments; PowerShell automatically encloses paths with spaces in "..."
, if needed:
cmd /c echo (Get-ChildItem -Filter *.txt).FullName
Generally, note that PowerShell's wildcard patterns are more powerful than those of the host platform's file-system APIs, and notably include support for character sets (eg [ab]
) and ranges (eg [0-9]
); another important difference is that ?
matches exactly one character, whereas the native file-system APIs on Windows match none or one .
-Filter
parameter of file-processing cmdlets such as Get-ChildItem
, the host platform's patterns are used, which - while limiting features - improves performance; a caveat is that on Unix-like platforms ?
then seemingly acts like on Windows, ie causing it to match none or one character. cmd.exe
(Command Prompt, the legacy shell) :
cmd.exe
does not support calling executables by wildcard pattern; some of cmd.exe
's internal commands (eg, dir
and del
) and some standard external programs (eg, attrib.exe
) do perform their own globbing; otherwise you must perform globbing manually , up front :
where.exe
, the external program for discovering external programs fundamentally only supports wildcard patterns in executable names (eg where find*.exe
), not in paths , which limits wildcard-based lookups to executables located in directories listed in the PATH
environment variable.
:: 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
Globbing via dir
appears to be limited to wildcard characters in the last path component:
:: 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*
Using manual globbing results programmatically is quite cumbersome in cmd.exe
and requires use of for
statements (whose wildcard matching has the same limitations as the dir
command); for example, using the syntax for batch files ( .cmd
or .bat
files):
To use the resolved executable file path for invocation (assuming only one file matches):
@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%" /?
To pass matching filenames as multiple arguments to a single command:
@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%
On Unix -like platforms, POSIX-compatible shells such as Bash themselves perform globbing (resolving filename wildcard patterns to matching filenames), before the target command sees the resulting filenames , as part of a feature set called shell expansions (link is to the Bash manual).
On Windows , cmd.exe
(the legacy shell also known as Command Prompt) does NOT perform such expansions and PowerShell mostly does NOT .
That is, it is generally up to each target command to interpret wildcard patterns as such and resolve them to matching filenames.
That said, in PowerShell, many built-in commands, known as cmdlets , do support PowerShell's wildcard patterns , notably via the -Path
parameter of provider cmdlets, such as Get-ChildItem
.
Additionally and more generally, cmdlet parameters that represent names often support wildcards too; eg, Get-Process exp*
lists all processes whose image name start with exp
, such as explorer
.
Note that the absence of Unix-style shell expansions on Windows also implies that no semantic distinction is made between unquoted and quoted arguments (eg, *.txt
vs. "*.txt"
): a target command generally sees both as verbatim *.txt
.
In PowerShell , automatic globbing DOES occur in these limited cases :
Perhaps surprisingly, an executable file path can be invoked via a wildcard pattern :
as-is, if the pattern isn't enclosed in '...'
or "..."
and/or contains no variable references or expressions; eg:
C:\Windows\System3?\attri?.exe
via &
, the call operator , otherwise; eg:
& $env:SystemRoot\System32\attri?.exe
However, this feature is of questionable utility - When would you not want to know up front what specific executable you're invoking? - and it is unclear whether it was implemented by design , given that inappropriate wildcard processing surfaces in other contexts too - see GitHub issue #4726 .
Additionally, up to at least PowerShell 7.2.4, if two or more executables match the wildcard pattern, a misleading error occurs, suggesting that no matching executable was found - see GitHub issue #17468 ; a variation of the problem also affects passing a wildcard-based path (as opposed to a mere name ) that matches multiple executables to Get-Command
.
In POSIX-compatible shells, the multi-match scenario is handled differently, but is equally useless: the first matching executable is invoked, and all others are passed as its arguments .
On Unix -like platforms only, PowerShell emulates the globbing feature of POSIX-compatible shells when calling external programs , in an effort to behave more like the platform-native shells; if PowerShell didn't do that, something as simple as ls *.txt
would fail, given that the external /bin/ls
utility would then receive verbatim *.txt
as its argument.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.