找不到路径 _ 因为它不存在

时间:2021-01-03 10:53:44

标签: powershell hardlink new-item

我正在尝试在 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 个循环):

[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.

无论有没有管理权限都会出现相同的错误。

我需要做什么才能让它发挥作用?

1 个答案:

答案 0 :(得分:0)

尝试以下操作:

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 common parameter预览操作。一旦您确定操作会满足您的要求,请移除 -WhatIf

  • -Filter '*[1]*' 预过滤 Get-ChildItem 输出以仅包含名称包含子字符串 [1] verbatim 的文件,因为 -Filter 参数使用一种文件系统原生通配符语言,[] 视为元字符。

    • 相比之下,使用 PowerShell 更强大的 wildcard patterns'*[1]*' 将匹配任何仅包含 1 的名称,因为 [...] 被解释为字符集或范围。使用 -likewildcard matching operator 运算符,您必须使用 '*`[1`]*'(转义要使用 ` 逐字解释的元字符)来逐字查找 {{1} } 子字符串。
  • [1] 将匹配项限制为文件,因为硬链接仅支持文件,不支持目录。

  • -File 使用 only -Path (Join-Path .\[1] $file) 参数 - 而不是仅目录路径 -Path 参数与仅文件名 {{ 1}} 参数 - 确保参数被视为 literal(逐字)路径,而不解释通配符元字符,例如 -Path-Name

    • 遗憾的是,将 [] 结合会导致 -Path 参数被解释为通配符模式
  • -Name 按需创建目标目录(如果需要),但请注意,它还会替换任何预先存在的目标文件。

  • 仅适用于 Windows PowerShell-Path 转义目标路径以便在解释时逐字处理它作为通配符模式,不幸的是,-Force 参数被解释为。不执行此转义会提示您看到的错误。

    • 警告

      • PowerShell [Core] 7+ 中,GitHub proposal #13136 中的一项重大更改已获批准 - 更明智地 - 处理 { {1}} 参数作为文字(逐字)路径,在这种情况下,您可以简单地使用 ([WildcardPattern]::Escape($path))

      • 但是,从 PowerShell 7.1 开始,此更改尚未实施,不幸的是,针对包含 -Target-Target 的路径的目标目前已完全中断 - 参见GitHub issue #14534

请注意,许多(但不是全部)文件处理 cmdlet 提供 -Target $path 参数以显式传递要采用的路径字面(逐字),而 [ 参数- 通常第一个位置参数的隐含参数 - 旨在接受通配符模式。

因此,您可以按照以下方式使用 Move-Item 进行原始方法:

]

注意:与 -LiteralPath 不同,-Path# 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-ItemMove-Item 参数不同,-ForceMove-Item 更明智地解释其参数字面(逐字)。< /p>