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



我正试图在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_movelist[1] dir1
New-Item:
Line |
5 |  New-Item -Path ".``[1``]" -Name $file -Type HardLink -Target "$path …
|  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Cannot find path 'D:test_movelist[1] dir1' because it does not exist.

无论是否具有管理权限,都会出现相同的错误。

我该怎么做才能让它发挥作用?

尝试以下操作:

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]逐字的文件,因为-Filter参数使用文件系统本机通配符语言,而[]视为元字符。

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

  • -Path (Join-Path .[1] $file)仅使用-Path参数,而不是仅使用目录路径的-Path参数和仅使用文件名的-Name参数,这确保该参数被视为文字(逐字(路径,而不解释通配符元字符,如[]

    • 遗憾的是,将-Path-Name组合会导致-Path参数被解释为通配符模式
  • -Force根据需要创建目标目录,但请注意,它也会替换任何预先存在的目标文件。

  • Windows PowerShell:([WildcardPattern]::Escape($path))转义
    -Target(也称为-Value(参数(目标路径(,以便逐字处理,因为很遗憾,它被解释为通配符模式。未执行此转义会提示您看到的错误。

    • 洞穴

      • PowerShell[Core]7+中,GitHub提案#113136中批准了一项突破性的更改,以便更明智地将-Target参数视为文字(逐字(路径。在这种情况下,只需使用-Target $path即可。

      • 然而,从PowerShell 7.2.2开始,这一更改尚未实现,不幸的是,针对包含[]的路径的操作目前已完全中断-请参阅GitHub问题#14534。

        • 从PowerShell 7.2.2开始,必须对进行两次转义(!(才能使其工作:([WildcardPattern]::Escape([WildcardPattern]::Escape($path)))

请注意,许多(但不是所有(文件处理cmdlet都提供了-LiteralPath参数,以显式传递要从字面上(逐字逐句(获取的路径,而-Path参数-通常是第一个位置参数的隐含参数-旨在接受通配符模式。

因此,您可以使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不会按需创建目标目录。另一方面,与New-Item-Target参数不同,Move-Item-Destination更明智地从字面上(逐字逐句(解释其参数。

相关内容

最新更新