Попытка сохранить указанный c файл с его именем в папке - PullRequest
0 голосов
/ 24 февраля 2020

Во-первых, извините меня, потому что я новичок ie, и мне очень сложно сделать простой скрипт.

Я пытаюсь сохранить некоторые специфические c файлы с родительским каталогом

Пример: Здесь я хочу сохранить имя "Folder2" "Folder4" и файлы 2, 3, 6.

Folder1\Folder2\
              |===> File1
              |===> File2
              |===> File3
Folder3\Folder4\
              |===> File4
              |===> File5
              |===> File6

Для создания этого дерева в моем сохранении:

Save\Folder2\
              |===> File2
              |===> File3
Save\Folder4\
              |===> File6

Я пытаюсь это сделать:

$Src = "C:\Folder3\"
$Dst = "C:\Save\"

Get-ChildItem -Path $Src -Recurse -Name "File2.txt" | Where-Object {$_.PSIsContainer} | ForEach-Object {[System.IO.Path]::GetDirectoryName($_); New-Item -Path $Dst -Name $_}

Я почти уверен, что это действительно легко, но я действительно не понимаю, как работает powershell.

Спасибо

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

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

Folder1\Folder2\

... что вы ничего не делаете в своем коде, но хотите, чтобы файлы из это.

<#
$Src = "C:\Folder3\"
$Dst = "C:\Save\"
#>

Итак, тогда это. Если это не опечатка.

$src1 = 'Folder1\Folder2\'
$Src3 = 'Folder3\Folder4\'
$Dst = 'C:\Save\'

Вы запрашиваете здесь только один файл

# Get-ChildItem -Path $Src -Recurse -Name "File2.txt" |

$src1,$src3 | 
ForEach ($File -in (Get-ChildItem -Path $PSItem.FullName) |

Это также означает, что вы не знаете, где этот файл находится в дереве, поэтому , используя -Recurse для сканирования всех из них. Не сканируйте, если вам не нужно. Кроме того, почему вы ищете папку здесь, когда вы запрашиваете только один файл или набор файлов?

Where-Object {
$_.PSIsContainer} |

Вы делаете кучу необработанных библиотечных вещей, когда есть собственные командлеты / свойства для этого такие вещи

ForEach-Object {
# [System.IO.Path]::GetDirectoryName($_)
$PSItem.DirectoryName

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

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

* Folder1 \ Folder2 *

          |===> File1
          |===> File2
          |===> File3

... до

* Сохранить \ Папка2 *

          |===> File2
          |===> File3

... и от

* Папка3 \ Папка4 *

          |===> File4
          |===> File5
          |===> File6

... в

* Сохранить \ Папка4 * | ===> Файл6

If ($Filename -eq 'File2|File3')
{Copy-Item -Path "$Dst\$($Filename.DirectoryName)" -Force}
}

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

Опять же, сначала потренируйтесь. Это практически все бесплатно на Youtube, бесплатные онлайн книги , et c. Это поможет настроить ваш ум и навыки для ограничения путаницы, ошибок, плохого кода / практики / привычек и т. Д. c.

Так что, как вы видите, в вашем коде много неуместного против того, что вы после. В основном из-за того, что вы говорите, что на самом деле не знаете, как работает PowerShell.

Итак, наряду с другими предлагаемыми ответами, попробуйте что-то вроде ниже. Тем не менее, поскольку вы не потратили много времени на изучение PowerShell, это может не иметь смысла, даже если это работает для вас. Итак, снова перейдите на Youtube, чтобы сначала набрать скорость, прежде чем пытаться чей-либо код.

Просто найдите:

Используйте встроенные файлы справки и приведенные там примеры, попрактикуйтесь с ними и прочитайте Снова справочные файлы:

# See all help topics
Select-Object -Property Name, Synopsis |
Out-GridView -Title 'Select Topic' -OutputMode Multiple |
ForEach-Object { Get-Help -Name $_.Name -ShowWindow }

explorer "$pshome\$($Host.CurrentCulture.Name)"

# get function / cmdlet details
Get-Command -Name Copy-Item -Syntax
(Get-Command -Name Copy-Item).Parameters.Keys
Get-help -Name Copy-Item -Full
Get-help -Name Copy-Item -Online
Get-help -Name Copy-Item -Examples


Get-Command -Name Move-Item -Syntax
(Get-Command -Name Move-Item).Parameters.Keys
Get-help -Name Move-Item -Full
Get-help -Name Move-Item -Online
Get-help -Name Move-Item -Examples

Итак, в PowerShell всегда есть несколько способов сделать X или Y, некоторые решения более элегантны, чем другие, но вот пример того, что вы чувствуете после. Опять же, это очень грубая вещь, и ее можно настроить, чтобы улучшить, или go по-другому, в зависимости от варианта использования.

# Clear the screen
Clear-Host

# Set source and destination resources
$src1 = 'D:\Temp\ParentFolder'
$src3 = 'D:\Test\Reference'
$Dst = 'D:\Save'

# Pipe in the source items
$src1,$src3 | 
<#
Loop through the source items
#>
ForEach{
    <#
    Read the source items to locate specific files
    #>
    Get-ChildItem -Path $PSItem -Include Test_Audio.csv,hello.bat,ParentWELCOM98.WAV -Recurse | 
    ForEach {
        <#
        Target only specif cfile names
        #>
        If($PSitem -match 'Test_Audio.csv|hello.bat')
        {
            <#
            If this is a match then copy to the destination root by adding the directory of the filename
            Using teh -WhatIf to validate the action before deciding to remove the -WhatIf for actual taks completion.
            #>
            Copy-Item -Path $PSitem.FullName -Destination $Dst\$($PSitem.Directory.BaseName) -WhatIf
        }
        Else 
        {
            <#
            If this is a match then copy to the destination root by adding the directory of the filename
            Using teh -WhatIf to validate the action before deciding to remove teh -WhatIf for actual taks completion.
            #>
            Copy-Item -Path $PSitem.FullName -Destination $Dst\$($PSitem.Directory.BaseName) -WhatIf
        }
    }
}

# Results
<#
What if: Performing the operation "Copy File" on target "Item: D:\Temp\ParentFolder\ParentWELCOM98.WAV Destination: D:\Save\ParentFolder".
What if: Performing the operation "Copy File" on target "Item: D:\Temp\ParentFolder\Test_Audio.csv Destination: D:\Save\ParentFolder".
What if: Performing the operation "Copy File" on target "Item: D:\Test\Reference\hello.bat Destination: D:\Save\Reference".
#>

Когда вы удалите - Whatif и использование -Force, все будет завершено и элементы будут созданы.

0 голосов
/ 24 февраля 2020

Если вы фильтруете так, чтобы возвращались только контейнеры (каталоги), у вас никогда не будет файлового объекта для копирования.

Если мы знаем больше о том, что вы пытаетесь сделать, мы могли бы, вероятно, poli sh это хорошо. Итак, это только начало, но попробуйте что-то вроде:

$SrcRoot = "C:\temp\01-24-20"
$DstRoot = "C:\temp\Save\"

Get-ChildItem -Path $SrcRoot -Recurse -Directory | 
ForEach-Object{
    $Root   = $_ # Makes it easier to reference the object in the outer ForEach loop.
    $DstSub = New-Item -Path $DstRoot -Name $Root.Name -ItemType Directory

    # > From your initial code it doesn't look like you need recursion here.
    # > Also you may want to add the -Filter parameter to add a wildcard pattern
    Get-ChildItem $Root.FullName -File | 
    ForEach-Object{
        # > Add an If block below to make the copy conditional.
        Copy-Item $_ -Destination $DstSub
    }
}

Дайте нам знать, как это происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...