2015-04-09 2 views
0

Я пытаюсь написать PowerShell, чтобы пройти через папку и выполнить различные операции в зависимости от имени файла. Проблема, с которой я столкнулась, - это когда я использую Case Switch $ _, содержит только базовое имя (см. Ниже). Есть ли способ доступа к его родительскому элементу? Мне нужно получить полный путь к файлу. Я где-то видел, что вы можете $ _. Parent.FullPath, но это кажется неправильным.Ссылка на родительский элемент Piped Element

Get-ChildItem -Path "C:\Folder\" -Filter "*.xls" | ForEach-Object { 
    switch -Wildcard ($_.BaseName){ 
     "*test1*" { 
      Write-Host "Test1" 
      Write-Host $_.Parent.FullName 
     } 
     "*test2*" { 
      Write-Host "Test2" 
      Write-Host $_.Parent.FullName 
     } 
     "*tets3*" { 
      Write-Host "Test3" 
      Write-Host $_.Parent.FullName 
     } 
    } 
} 

Я знаю, что если я изменил от Swtich случая к IF заявления, которые я бы иметь доступ к FullName.

+1

Вы используете basename, поэтому внутренний '$ _' именно это. Сохраните внешнюю '$ _' в другой переменной, если вы хотите использовать ее во внутреннем блоке. –

+0

Возможный дубликат [PowerShell XML: Switch vs if] (http://stackoverflow.com/questions/29081667/powershell-xml-switch-vs-if) –

+0

Вы можете включить Fullname, а затем использовать Split-Path для получения родитель. – mjolinor

ответ

1

Когда вы находитесь в инструкции Switch, вы в основном находитесь в новом конвейере, поэтому вы теряете ссылку на родительский объект.

За исключением, вы сохранили этот объект в другом месте. Например, перед оператором Switch я добавил $file = $_, чтобы сохранить ссылку на текущий объект в $ файле. Когда я запускаю это сейчас, это то, что я вижу:

$file = $_ 
    switch -Wildcard ($_.BaseName){ 
     "*test1*" { 
      Write-Host "Test1" 
      Write-Host $file.FullName} 
[...] 

>Test1 
C:\temp\Test1.txt 
Test12 
C:\temp\Test12.txt 
Test100 
C:\temp\Test100.txt 

Теперь вы можете сослаться на текущий объект снова, используя $ файл и выбрать любой из его свойств. Надеюсь, это поможет вам в правильном направлении.

0

Извините, я даже не рассматривал этот вопрос только сейчас. У вас есть принятый ответ, и я рад, что вы смогли его обработать, но я хотел добавить еще один вариант ...

Вы можете включить объект в целом и просто проверить на сценариях, таким образом у вас есть доступ ко всему объекту FILEINFO, а не только свойство BASENAME:

Switch((Get-ChildItem -Path "C:\Folder\" -Filter "*.xls")){ 
    {$_.BaseName -like "*Test1*"} {"Test1";$_.FullName} 
    {$_.BaseName -like "*Test2*"} {"Test2";$_.FullName} 
    {$_.BaseName -like "*Test3*"} {"Test3";$_.FullName} 
} 

в качестве альтернативы вы можете запустить матч RegEx в Где заявление и захватить вещи, которые вы ищете, а затем вернуться $Matches[1] и FullName имущество в цикле ForEach:

Get-ChildItem -Path "C:\Folder\" -Filter "*.xls" | Where{$_.basename -match "(test1|test2|test3)"} | ForEach{$Matches[1];$_.FullName} 

Любой из них предоставит вам желаемый результат. Ни один из них напрямую не отвечает на ваш вопрос о том, как получить доступ к родительскому элементу, но они достаточно прочные способы избежать необходимости назначать его переменной и затем ссылаться на эту переменную позже.

Смежные вопросы