Выполнение команды Powershell с переменным параметром -Path - PullRequest
1 голос
/ 01 ноября 2019

Может ли кто-нибудь объяснить мне следующее поведение?

PS C:\Users\Kenny> $filePath = "C:\\Complicated.File.Path.That.Has.Special-Chars`[but-no.spaces`]and.definitely.exists\"
PS C:\Users\Kenny> cd $filePath
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd $filePath
+ ~~~~~~~~~~~~~~~~                                 
    + CategoryInfo          : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
   xception
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

PS C:\Users\Kenny> cd 'C:\\Complicated.File.Path.That.Has.Special-Chars`[but-no.spaces`]and.definitely.exists\'
PS C:\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists> cd c:
PS C:\Users\Kenny> Write-Host $filePath
C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\
PS C:\Users\Kenny> cd "$filePath"
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd "$filePath"
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
   xception
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

PS C:\Users\Kenny> cd ${filePath}
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd ${originalPath}
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
   xception
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

PS C:\Users\Kenny> cd ${$filePath}
cd : Cannot process argument because the value of argument "path" is null. Change the value of argument "path" to a
non-null value.
At line:1 char:1
+ cd ${$filePath}
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-Location], PSArgumentNullException
    + FullyQualifiedErrorId : ArgumentNull,Microsoft.PowerShell.Commands.SetLocationCommand

PS C:\Users\Kenny> cd $($filePath)
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd $($filePath)
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
   xception
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

Если бы у меня была копейка за каждую минуту, которую я потратил впустую из-за настойчивого утверждения PowerShell о том, что обратные черты, кавычки и другие метасимволы в самый раз , я был бы самым богатым человеком на Земле! Кто-нибудь, пожалуйста, спасите меня от этого безумия!

И кстати, то, что я на самом деле пытаюсь сделать, это пройтись по куче папок и удалить все, что не видеофайл, например ...

Remove-Item -Path $filePath -Recurse -Exclude '*.avi','*.mkv','*.mp4'

... который не работает (предположительно) по той же причине: невозможность передать переменную параметру -Path. И если кто-то чувствует себя действительно щедрым, они также могут помочь мне с этим . MTIA! : D

Ответы [ 3 ]

1 голос
/ 01 ноября 2019

Специальные символы - это так весело в PS, верно?

-LiteralPath работает точно так же, как объяснил Патрик, но они не допускают подстановочные знаки;потому что они буквальные.

Вы пытались использовать одинарные кавычки "вместо двойных кавычек". Это позволяет вам экранировать специальные символы, все еще оценивая символы подстановки. Попробуйте следующие команды:

New-Item -Path 'C:\Users\username\PSScripts\bracket`[\te$t.txt'
Get-Item -Path  'C:\Users\username\PSScripts\bracket`[\*'

Кроме того, если это помогает, я использую VSCode для большинства сценариев и, если вы используете завершение табуляции, он правильно отформатирует это для вас.

Надеюсь, это поможет!

1 голос
/ 01 ноября 2019

Используйте -LiteralPath вместо -Path, поскольку некоторые специальные символы интерпретируются как -Path.

Remove-Item -LiteralPath
0 голосов
/ 01 ноября 2019

Решением моей общей проблемы стала следующая строка моего пакетного скрипта:

powershell -Command "Get-ChildItem -Recurse -LiteralPath %filePath% | Where-Object Extension -match '^(?!(\.avi|\.mkv|\.mp4)$)' | Remove-Item"

Регулярное выражение было труднее всего понять, так как я раньше не использовал отрицательный прогноз, но после ~2 часа общего времени, потраченного на эту одну строку кода , наконец-то работает!

...