Как изменить этот сценарий PS для перемещения файлов в правильные папки? - PullRequest
0 голосов
/ 27 января 2020

Мой текущий сценарий PS:

$loc = "C:\Users\USER\Desktop\New folder1"
$files = Get-ChildItem -Path $loc
for ($i=0; $i -lt $files.Count; $i++) 
{
$outfile = $files[$i].FullName
$filename = Split-Path -Path $outfile -Leaf -Resolve
$Year = $filename -replace "Status_\d{0}(\d{4})[\d_]*.txt",'$1'
$Month = $filename -replace "Status_\d{4}(\d{2})[\d_]*.txt",'$1'
$folderYYYY = Join-Path -Path  $loc -ChildPath $Year
$folderMM = Join-Path -Path $folderYYYY -ChildPath $Month
$ExistsYYYY = Test-Path $folderYYYY
$ExistsMM = Test-Path $folderMM
If (!$ExistsYYYY) 
{ 
    New-Item -Type directory -Path $folderYYYY
}
If (!$ExistsMM)
{ 
    New-Item -Type directory -Path $folderMM
} 
Move-Item $outfile $folderMM
}

Этот сценарий должен перемещать файлы, находящиеся в данный момент в каталоге $ lo c, в подпапки YYYY-MM. Если подпапка ГГГГ или ММ не существует, она создается. Если путь к подпапке уже существует, то файл перемещается в эту подпапку.

Имя файла всегда имеет следующий формат:

Status_20180215_074559.txt

Так что для указанного выше файла YYYY будет отображаться на 2018 и MM будет отображаться в 02

Из тестирования скрипта - если подпапка YYYY не существует, то скрипт отлично работает. Если подпапка YYYY уже существует, я получаю следующие пути, созданные сценарием:

C:\Users\USER\Desktop\New folder1\2018
C:\Users\USER\Desktop\New folder1\2018\02
C:\Users\USER\Desktop\New folder1\2018\2018

Файл перемещен в указанный ниже путь с помощью вышеуказанного сценария:

C:\Users\USER\Desktop\New folder1\2018\02

Я также получаю следующее сообщение об ошибке:

Move-Item : Access to the path 'C:\Users\USER\Desktop\New folder1\2018' is denied. 
At line:14 char:10 
+ Move-Item <<<<  $outfile $folder 
+ CategoryInfo : WriteError: (C:\Users\USER...ew folder1\2018:DirectoryInfo) [Move-Item], IOException 
+ FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand 

Любой способ остановить создание следующего пути:

C:\Users\USER\Desktop\New folder1\2018\2018

Кроме того, как решить возникшую ошибку?

Большое спасибо

Редактировать: пробовал скрипт @Theo, но я получаю следующие проблемы:

enter image description here

Затем я удалил все комментарии и пустые строки, думая, что это может вызвать проблемы где-то, но затем я получаю следующую ошибку:

enter image description here

Итак, после некоторой помощи от кого-то еще проблема с моим скриптом заключалась в строке $ files - он должен был искать только файлы:

$files = Get-ChildItem -Path "$loc\*.txt"

Кроме того, исправленный скрипт PS, очень услужливо предоставленный @Theo, также работает, так как я есть версия PS 2

1 Ответ

1 голос
/ 27 января 2020

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

Кроме того, намного проще перенаправить результаты из Get-Childitem с использованием ForEach-Object и в этом l oop используйте переменную $_ automati c.

Примерно так:

$loc = "C:\Users\USER\Desktop\New folder1"

Get-ChildItem -Path $loc -File -Filter 'Status_*' |        # get a list of files with names starting with 'Status_'
    Where-Object { $_.BaseName -match '_\d{8}_\d{6}$' } |  # filter files that have the '_date_time' format 
    ForEach-Object {                                       # loop through
        # join the year and month as partial destination path
        $targetpath  = '{0}\{1}' -f $_.Name.Substring(7,4), $_.Name.Substring(11,2)
        # ceate the full destination path for the file
        $destination = Join-Path -Path $loc -ChildPath $targetpath

        # check if the path exists and if not, create it
        if (!(Test-Path -Path $destination -PathType Container)) {
            $null = New-Item -Path $destination -ItemType Directory
        }
        # now move the file to the destination path
        $_ | Move-Item -Destination $destination
    }


Edit

Кажется, вы используете PowerShell версии 2.0, а затем переключатель -File не существует. Для этой версии вам нужно адаптировать код так:

$loc = "C:\Users\USER\Desktop\New folder1"

Get-ChildItem -Path $loc -Filter 'Status_*' |
    Where-Object { !$_.PSIsContainer -and  $_.BaseName -match '_\d{8}_\d{6}$' } | 
    ForEach-Object {
        # join the year and month as partial destination path
        $targetpath  = '{0}\{1}' -f $_.Name.Substring(7,4), $_.Name.Substring(11,2)
        # ceate the full destination path for the file
        $destination = Join-Path -Path $loc -ChildPath $targetpath

        # check if the path exists and if not, create it
        if (!(Test-Path -Path $destination -PathType Container)) {
            $null = New-Item -Path $destination -ItemType Directory
        }
        # now move the file to the destination path
        $_ | Move-Item -Destination $destination
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...