我想知道是否有任何方法可以在 Windows 上實作這種行為,例如:
/b?n/ca? /etc/pa??wd -> 執行 'cat /etc/passwd'
uj5u.com熱心網友回復:
在 PowerShell 中,您可以使用決議路徑中的通配符并顯示路徑內容的Resolve-Path 。
示例:我想從 Windows SDK 中找到 signtool.exe,它通常位于“c:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe”中,可能還有其他安裝的版本。
所以我可以使用:Resolve-Path 'c:\program*\Windows Kits\10\bin\*\x64\signtool.exe'
編輯:
如果你想直接執行它,你可以使用&呼叫運算子,例如
&(Resolve-Path 'c:\wind?ws\n?tepad.exe')
uj5u.com熱心網友回復:
除了 PowerShell 中的有限例外,在 Windows 上不支持shell 級別的通配 - 目標命令必須執行自己的通配符模式決議以匹配檔案名;如果不這樣做,則必須手動執行 globbing ,并將結果作為文字路徑傳遞;有關背景資訊,請參閱底部。
電源:
也許令人驚訝的是,您可以通過通配符模式呼叫可執行檔案,正如zett42指出的那樣,盡管這種行為是有問題的(見底部):
# Surprisingly DOES find C:\Windows\System32\attrib.exe # and invokes it. C:\Windows\System3?\attr*.exe /?Get-Command通常,您可以通過cmdlet發現命令,包括外部程式。
PowerShell 中的許多檔案處理 cmdlet都執行它們自己的通配符(例如
Get-ChildItem,Remove-Item);如果您正在呼叫不支持的命令,尤其是不支持的外部程式,則必須預先手動執行 globbing ,除非在類 Unix平臺上呼叫 _external 程式時,PowerShell會執行自動 globbing(見底部):用于
Convert-Path獲取匹配檔案或目錄的完整檔案系統本機路徑。- 雖然
Resolve-Path也可以作業,但它回傳您需要訪問其屬性以獲取相同資訊的物件(將這些物件字串化,就像您將它們傳遞給外部程式時隱式發生的那樣,產生它們的屬性,這可能基于僅 PowerShell 的外部驅動器程式和 .NET API 對此一無所知。).ProviderPath.Path
- 雖然
為了更好地控制匹配
Get-ChildItem的內容,根據需要使用和訪問結果物件.Name或.FullName屬性;例如,Get-ChildItem允許您僅將匹配限制為檔案(-File) 或目錄(-Directory)。PowerShell 使以編程方式使用手動執行的 globbing 的結果變得容易;以下示例將
*.txt當前目錄中所有檔案的完整路徑作為單獨的引數傳遞給cmd.exe'echo命令;如果需要, PowerShell 會自動將路徑用空格括起來"...":cmd /c echo (Get-ChildItem -Filter *.txt).FullName通常,請注意 PowerShell 的通配符模式比主機平臺的檔案系統 API 更強大,尤其是包括對字符集(例如
[ab])和范圍(例如[0-9])的支持;另一個重要區別是只?匹配一個字符,而 Windows 上的本機檔案系統 API 匹配none 或一個.- 但是,當使用
-Filter諸如 等檔案處理 cmdlet 的引數時Get-ChildItem,會使用主機平臺的模式,這會在限制功能的同時提高性能;需要注意的是,在類 Unix 平臺上?看起來就像在 Windows 上一樣,即導致它不匹配任何字符或匹配一個字符。
- 但是,當使用
cmd.exe(命令提示符,舊版 shell):cmd.exe不支持通過通配符模式 呼叫可執行檔案;的一些cmd.exe內部命令(例如,dir和del)和一些標準的外部程式(例如,attrib.exe)確實執行它們自己的通配符;否則,您必須預先手動執行globbing:where.exe,用于發現外部程式的外部程式基本上只支持可執行檔案名稱(例如where find*.exe)中的通配符模式,而不支持路徑中的通配符模式,這將基于通配符的查找限制為位于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似乎僅限于最后一個路徑組件中的通配符::: 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*以編程方式使用手動 globbing 結果非常麻煩,
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 兼容的 shell(如 Bash )本身在目標命令看到生成的檔案名之前執行globbing(將檔案名通配符模式決議為匹配的檔案名),作為稱為shell 擴展的功能集的一部分(鏈接到 Bash手動的)。
在Windows上,
cmd.exe(舊 shell 也稱為命令提示符)不執行此類擴展,而 PowerShell大多不執行。也就是說,通常由每個目標命令來解釋通配符模式并將它們決議為匹配的檔案名。
也就是說,在 PowerShell 中,許多稱為cmdlet的內置命令確實支持 PowerShell 的通配符模式,特別是通過提供程式
-Pathcmdlet 的引數,例如.Get-ChildItem此外,更一般地說,表示名稱的 cmdlet 引數通常也支持通配符。例如,
Get-Process exp*列出所有映像名稱以 開頭的行程exp,例如explorer.請注意,Windows 上沒有 Unix 樣式的 shell 擴展也意味著在未參考和參考的引數(例如vs. )之間沒有語意區別:目標命令通常將兩者視為verbatim。
*.txt"*.txt"*.txt
在PowerShell中,在這些有限的情況下會發生自動通配:
也許令人驚訝的是,可執行檔案路徑可以通過通配符模式呼叫:
照原樣,如果模式沒有包含在
'...'或"..."和/或不包含變數參考或運算式;例如:C:\Windows\System3?\attri?.exevia
&,呼叫操作員,否則;例如:& $env:SystemRoot\System32\attri?.exe但是,此功能的實用性值得懷疑——您什么時候不想預先知道您正在呼叫什么特定的可執行檔案?-鑒于在其他背景關系中也存在不適當的通配符處理表面,因此尚不清楚它是否是通過設計實作的 - 請參閱GitHub 問題 #4726。
此外,至少在 PowerShell 7.2.4 之前,如果兩個或多個可執行檔案與通配符模式匹配,則會出現誤導性錯誤,提示未找到匹配的可執行檔案 - 請參閱GitHub 問題 #17468;該問題的一個變體還影響傳遞與多個可執行檔案匹配的基于通配符的路徑(而不是僅僅name)到
Get-Command.在與 POSIX 兼容的 shell 中,多重匹配場景的處理方式不同,但同樣無用:呼叫第一個匹配的可執行檔案,所有其他的都作為其引數傳遞。
僅在類 Unix平臺上,PowerShell在呼叫外部程式時模擬POSIX 兼容 shell 的 globbing 特性,以努力表現得更像平臺原生 shell;如果 PowerShell 不這樣做,那么簡單的事情
ls *.txt就會失敗,因為外部/bin/ls實用程式隨后將逐字*.txt接收作為其引數。- 但是,從 PowerShell 7.2.4 開始,此仿真有局限性:
- 無法使用包含空格的通配符模式- 請參閱GitHub 問題 #10683。
- 無法包含隱藏檔案 - 請參閱GitHub 問題 #4683。
- 7.3預覽版中提供的一項仍處于試驗階段的功能,自動將基于 PowerShell 驅動器的通配符模式轉換為其底層本機檔案系統路徑;但是,此功能目前過于熱心 - 請參閱GitHub 問題 #13640 - 并且天生就有誤報的風險 - 請參閱GitHub 問題 #13644
PSNativePSPathResolution
- 但是,從 PowerShell 7.2.4 開始,此仿真有局限性:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/484865.html
上一篇:Java如何在不需要安裝其他開發工具的情況下制作Windows應用程式?
下一篇:有人可以解釋這個sed命令嗎?
