我在 Windows 7 上使用 PowerShell,并编写脚本将一堆文件从一个文件夹结构复制到另一个文件夹结构。有点像编译。 PowerShell Copy-Item
cmdlet 认为方括号 [ ] 是某种通配符,由于某种原因我无法逃脱它们。
我无法使用 -LiteralPath
,因为我想使用星号 * 通配符,因为文件名有一个日期作为文件名的一部分,并且日期会更改。日期用作版本号。
This post很有帮助,但没有多少刻度(每个括号 2 倍或 4 倍)逃脱方括号。
我没有收到错误; PowerShell 的行为与我输入了错误的文件名相同。
这是我正在处理的特定行:
#to Fusion Server
Copy-item -Path $FSG\$SW\0.RoomView.Notes\starter\"[RoomView] Versions explained*.pdf" -Destination $FSG\$containerFolder\$rootFolder\"Fusion Server"\
这就是全部:
# Compiles the Fusion packet for distribution
###############################
###########Variables###########
###############################
#folder structure
$FSG = "F:\FSG"
$containerFolder = "Packet.Fusion for IT and AV Professionals"
$rootFolder = "Fusion for IT and AV pros $(Get-Date -format “MM-dd-yyyy”)"
$subRoot1 = "Fusion Server"
$subRoot2 = "Scheduling Enhancement and Panels"
$subRoot2sub1 = "Scheduling Panels"
$subRoot3 = "SQL Server"
#source folders
$HW = "0.Hardware"
$3SMDoc = "0.Hardware\TPMC-3SM.Documentation"
$4SMDoc = "0.Hardware\TPMC-4SM.Documentation"
$4SMDDoc = "0.Hardware\TPMC-4SM-FD.Documentation"
$730Doc = "0.Hardware\TSW-730.Documentation"
$730OLH = "0.Hardware\TSW-730.OLH"
$CENRVS = "0.Hardware\CEN-RVS.Notes"
$ProjMgmt = "0.Project Management"
$SW = "0.Software"
$RVLicensing = "0.Software\0.RoomView.License"
$RVNotes = "0.Software\0.RoomView.Notes"
$SQLLicensing = "0.Software\database.SQL.Licensing"
$SQLNotes = "0.Software\database.SQL.Notes"
$FRVMarketing = "0.Software\Fusion RV.Marketing"
$FRVNetworking = "0.Software\Fusion RV.Networking"
$FRVNotes = "0.Software\Fusion RV.Notes"
###############################
#create the directory structure
###############################
md -Path $FSG\$containerFolder -Name $rootFolder
cd $FSG\$containerFolder\$rootFolder
md "eControl and xPanels"
md "Fusion Server" #$subRoot1
md "Getting Started as a User"
md "Project Management"
md "RoomView Connected Displays"
md "Scheduling Enhancement and Panels" #$subRoot2
md "SQL Server" #$subRoot3
cd $FSG\$containerFolder\$rootFolder\$subRoot1
md "CEN-RVS"
md "Licenseing Information"
md "Networking"
md "Official Documentation"
md "Prerequisites, including powerShell script"
md "Product Info"
md "Requirements"
md "Tech Info"
md "Windows Authentication to Fusion RV"
cd $FSG\$containerFolder\$rootFolder\$subRoot2
md "Outlook Add-in"
md "Scheduling Panels" #$subRoot2sub1
cd $FSG\$containerFolder\$rootFolder\$subRoot2\$subRoot2sub1
md "TPMC-3SM"
md "TPMC-4SM"
md "TPMC-4SM-FD"
md "TSW-730"
cd $FSG\$containerFolder\$rootFolder\$subRoot3
md "Multi-database model only"
md "SQL Licensing"
cd $FSG\$containerFolder
#reset current folder
###############################
#copy the files
###############################
#Copy-Item -Path C:\fso\20110314.log -Destination c:\fsox\mylog.log
#To the root
Copy-item -Path $FSG\$ProjMgmt\starter\"Fusion Support Group Contact info*.pdf" -Destination $FSG\$containerFolder\$rootFolder\
Copy-item -Path $FSG\$containerFolder\"Fusion for IT and AV professionals release notes.txt" -Destination $FSG\$containerFolder\$rootFolder\
#to eControl and xPanels
Copy-item -Path $FSG\$SW\xpanel.Notes\starter\*.* -Destination $FSG\$containerFolder\$rootFolder\"eControl and xPanels"\
#to Fusion Server
Copy-item -Path $FSG\$SW\0.RoomView.Notes\starter\"[RoomView] Versions explained*.pdf" -Destination $FSG\$containerFolder\$rootFolder\"Fusion Server"\
我能做些什么来转义方括号并仍然使用
Copy-Item
的通配 rune 件名部分小命令?
最佳答案
在这种情况下,您必须使用带单引号的双反引号来转义括号。使用双引号字符串时,也可以使用四重反引号。
所以固定的代码行是:
Copy-item -Path $FSG\$SW\0.RoomView.Notes\starter\'``[RoomView``] Versions explained*.pdf' -Destination $FSG\$containerFolder\$rootFolder\'Fusion Server'\
关于文件路径和有线字符等的另一个好资源是阅读这篇文章:Taking Things (Like File Paths) Literally
编辑
Thanks to @mklement0 for highlighting that the true cause of this inconsistency is because of a bug currently in PowerShell1. This bug causes escaping of wildcard characters, as well as backticks with the default
-Path
parameter to behave differently than other parameters e.g. the-Include
and-Filter
parameters.
扩展 @mklement0's excellent answer , 和 comments ,以及以下其他答案:
为了更好地理解我们为什么需要 单引号 和 两个倒勾 在 这个情况; ( 和 突出显示 bug 和不一致)让我们通过一些示例来演示发生了什么:
Get-Item
和相关的 cmdlet(Get-ChildItem
、Copy-Item
等),处理 -Path
处理 的组合时参数不同转义通配符 和 未转义的通配符 *同时***!TLDR:我们需要单引号和双反引号组合的根本原因是底层 PowerShell 提供程序如何解析
-Path
通配符的参数字符串。它似乎为转义字符解析一次,第二次解析通配符。让我们通过一些例子来展示这个奇怪的结果:
首先,让我们创建两个名为
File[1]a.txt
的文件进行测试。和 File[1]b.txt
"MyFile" | Set-Content '.\File`[1`]a.txt'
"MyFriend" | Set-Content '.\File`[1`]b.txt'
我们将尝试不同的方法来获取文件。我们知道方括号
[ ]
是 wildcards ,因此我们需要使用 backtick character 来逃避它们。 .我们将尝试获取 一个 明确文件。
让我们从使用单引号文字字符串开始:
PS C:\> Get-Item 'File[1]a.txt'
PS C:\> Get-Item 'File`[1`]a.txt'
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019-09-06 5:42 PM 8 File[1]a.txt
PS C:\> Get-Item 'File``[1``]a.txt'
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019-09-06 5:42 PM 8 File[1]a.txt
对于单引号字符串,检索文件只需要一个反引号,但也可以使用两个反引号。
使用双引号字符串,我们得到:
PS C:\> Get-Item "File[1]a.txt"
PS C:\> Get-Item "File`[1`]a.txt"
PS C:\> Get-Item "File``[1``]a.txt"
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019-09-06 5:42 PM 8 File[1]a.txt
对于双引号字符串,正如预期的那样,我们可以看到我们需要两个反引号才能使其工作。
现在,我们要检索 两个文件 和 使用通配符。
让我们从单引号开始:
PS C:\> Get-Item 'File[1]*.txt'
PS C:\> Get-Item 'File`[1`]*.txt'
PS C:\> Get-Item 'File``[1``]*.txt'
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019-09-06 5:42 PM 8 File[1]a.txt
-a---- 2019-09-06 5:49 PM 10 File[1]b.txt
使用单引号,当我们有通配符时,我们需要 两个 套反引号。一个转义括号,第二个反引号转义我们在评估通配符时用来转义括号的反引号。
同样对于双引号:
PS C:\> Get-Item "File[1]*.txt"
PS C:\> Get-Item "File`[1`]*.txt"
PS C:\> Get-Item "File``[1``]*.txt"
PS C:\> Get-Item "File```[1```]*.txt"
PS C:\> Get-Item "File````[1````]*.txt"
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019-09-06 5:42 PM 8 File[1]a.txt
-a---- 2019-09-06 5:49 PM 10 File[1]b.txt
使用双引号,使用通配符进行评估会更加冗长。在这种情况下,我们需要 四 套回蜱。对于双引号,我们需要两个反引号来转义括号,另外两个反引号来转义转义字符,一旦涉及到星号通配符的评估。
编辑
如@mklement0 mentions ,此行为与
-Path
参数不一致,并且行为与 -Include
不同参数,其中只需要一个反引号即可正确转义括号。这可能会在更高版本的 PowerShell 中“修复”。1从 Windows PowerShell v5.1/PowerShell Core 6.2.0-preview.3 开始
关于powershell - 复制文件名中带有方括号 [] 的文件并使用 * 通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21008180/