powershell 找不到path _,因为它不存在

bkhjykvo  于 2023-11-18  发布在  Shell
关注(0)|答案(1)|浏览(210)

我试图在powershell中创建一个小脚本,将文件和目录移动到正确的本地化。我做了以下命令:

Get-ChildItem -Path '.\list\' | ForEach-Object { if ($($_.Name) -like '*[1]*') {
$file = $($_.Name)
$path = $($_.FullName)
echo "$file  ==>  $path"
Move-Item -Path $path -Destination .\[1]\}}

字符串
它检测正确的文件和目录,但不移动它们。
然后我决定修改一下命令,创建硬链接:

Get-ChildItem -Path '.\list\' | ForEach-Object { if ($($_.Name) -like '*[1]*') {
$file = $($_.Name)
$path = $($_.FullName)
echo "$file  ==>  $path"
New-Item -Path ".\``[1``]\" -Name $file -Type HardLink -Target "$path"}}


我收到了以下回应(只切到一个循环):

[1] dir1  ==>  D:\test_move\list\[1] dir1
New-Item:
Line |
   5 |  New-Item -Path ".\``[1``]\" -Name $file -Type HardLink -Target "$path …
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Cannot find path 'D:\test_move\list\[1] dir1' because it does not exist.


无论是否具有管理权限,都会出现相同的错误。
我要怎么做才能让它生效?

bqujaahr

bqujaahr1#

尝试以下操作:

Get-ChildItem -LiteralPath .\list -File -Filter '*[1]*' | ForEach-Object { 
  $file = $_.Name
  $path = $_.FullName
  "$file  ==>  $path" # implicit `echo` aka `Write-Output`
  New-Item -Force -Type HardLink `
           -Path (Join-Path .\[1] $file) `
           -Target ([WildcardPattern]::Escape($path)) ` # !! see PowerShell Core comments below
           -WhatIf
}

字符串
注意事项:上面的命令中的-WhatIf公共参数 * 预览 * 操作。一旦您确定该操作将执行您想要的操作,请删除-WhatIf

  • -Filter '*[1]*'预过滤Get-ChildItem输出,使其仅包括名称中包含子字符串[1]verbatim 的文件,因为-Filter参数使用的 filesystem-native XML语言不 * 将[]视为元字符。
  • 相比之下,对于PowerShell更强大的wildcard patterns'*[1]*'将匹配任何仅包含1的名称,因为[...]被解释为字符集或范围。你必须使用'*[1]*'(转义要用```逐字解释的元字符)来查找逐字的[1]子字符串。
  • -File将匹配项限制为 files,因为 hardlinks 仅支持文件,而不支持目录。
  • -Path (Join-Path .\[1] $file)使用 only 一个-Path参数-而不是一个仅目录路径的-Path参数与一个仅文件名的-Name参数的组合-这确保了参数被视为一个 * 文字 *(逐字)路径,而不解释[]之类的XML元字符。
  • 遗憾的是,将-Path-Name结合使用会导致-Path参数被解释为一个 * 重复模式 *。
  • -Force会根据需要创建目标 * 目录 *,但请注意,它也会替换任何 * 预先存在的 * 目标文件。
  • Windows PowerShell([WildcardPattern]::Escape($path))**转义

-Target(又名-Value)参数(目标路径),以便将其 * 逐字处理 *,因为不幸的是,它被解释为 * 一个转义模式 *。不执行此转义会导致您看到的错误。

*注意事项
*PowerShell [Core] 7+ 中,在GitHub proposal #13136中批准了一个突破性的更改-更明智地--Target参数视为 literal(逐字)路径,在这种情况下,您只需使用-Target $path

  • 但是,**截至PowerShell 7.3.8,此更改尚未实现,并且不幸的是,针对包含[]的路径目前 * 完全中断 * -请参阅GitHub issue #14534
    ***从PowerShell 7.3.8开始,您必须转义 * 两次 *(!)**才能使其工作:([WildcardPattern]::Escape([WildcardPattern]::Escape($path)))

请注意,许多(但不是所有)文件处理的xm 34n1x提供了一个-LiteralPath参数来显式地传递要采用的路径,而-Path参数-通常是第一个 * 位置 * 参数的 * 隐含 * 参数-旨在接受xm 35n1x模式。
因此,您可以使用Move-Item的原始方法,如下所示:

# Ensure that the target dir. exists.
# No escaping needed for -Path when not combined with -Name.
$null = New-Item -Type Directory -Path .\[1] -Force 

# Move the file, targeted with -LiteralPath, there.
# No escaping needed for -Destination.
Move-Item -LiteralPath $path -Destination .\[1]\


注意事项:与New-Item不同,Move-Item-Force不会按需创建目标目录。另一方面,Move-Item-Destination更合理地解释其参数,而不像New-Item-Target参数。

相关问题