Как удалить объект из массива в PowerShell?

Я использую Powershell 1.0 для удаления объекта из Массива. Вот мой сценарий:

param (
    [string]$backupDir = $(throw "Please supply the directory to housekeep"), 
    [int]$maxAge = 30,
    [switch]$NoRecurse,
    [switch]$KeepDirectories
    )

$days = $maxAge * -1

# do not delete directories with these values in the path
$exclusionList = Get-Content HousekeepBackupsExclusions.txt

if ($NoRecurse)
{
    $filesToDelete = Get-ChildItem $backupDir | where-object {$_.PsIsContainer -ne $true -and $_.LastWriteTime -lt $(Get-Date).AddDays($days)}
}
else
{
    $filesToDelete = Get-ChildItem $backupDir -Recurse | where-object {$_.PsIsContainer -ne $true -and $_.LastWriteTime -lt $(Get-Date).AddDays($days)}
}

foreach ($file in $filesToDelete)
{       
    # remove the file from the deleted list if it's an exclusion
    foreach ($exclusion in $exclusionList)
    {
        "Testing to see if $exclusion is in " + $file.FullName
        if ($file.FullName.Contains($exclusion)) {$filesToDelete.Remove($file); "FOUND ONE!"}
    }
}

Я понимаю, что Получают-ChildItem в возвратах powershell Систему. Тип массива. Я поэтому получаю эту ошибку при попытке использовать Удалить метод:

Method invocation failed because [System.Object[]] doesn't contain a method named 'Remove'.

То, что я хотел бы сделать, является $filesToDelete преобразования к ArrayList, и затем удалите использование объектов ArrayList. Удалить. Это хорошая идея или если я непосредственно управляю $filesToDelete как Системой. Массив в некотором роде?

Спасибо

6
задан Mark Allison 26 February 2010 в 11:23
поделиться

2 ответа

Нет пути сделать это через CSS, но вы можете расширить тип номера следующим образом:

    Number.prototype.formatMoney = function(c, d, t){
    var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "," : d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
       return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
    };

, затем использовать его следующим образом:

var count = 10000000;
count.formatMoney(2, '.', ' ')
-121--1265595-

Ссылка на статью имеет несколько хороших советов, которые могут быть легко ошибочно процитированы и неправильно поняты. И плохой совет.

Оставьте Java позади. Начни свежее. «не доверяйте своим инстинктам [на основе Java]». Говорить «контр-интуитивно» - вредная привычка в любой дисциплине программирования. Изучая новый язык, начинайте заново и бросайте привычки. Интуиция должна быть неправильной.

Языки различаются . В противном случае, они будут одним языком с другим синтаксисом, и будут простые переводчики. Потому что нет простых переводчиков, нет простого отображения. Это означает, что интуиция бесполезна и опасна.

  • «Статический метод в Java не переводится в метод Python». Такого рода вещи действительно ограничены и бесполезны. Python имеет статический метод декоратора. Он также имеет классовый метод декоратора, для которого Java не имеет эквивалента.

    Этот пункт, BTW, также включал в себя гораздо более полезные советы о том, чтобы не без необходимости завернуть все в класс. «Идиоматический перевод статического метода Java обычно является функцией уровня модуля».

  • Инструкция Java switch в Java может быть реализована несколькими способами. Во-первых, это обычно конструкция if elif elif . Статья в этом отношении бесполезна. Если вы абсолютно уверены, что это слишком медленно (и можете доказать это), вы можете использовать Python словарь как немного более быстрое отображение от значения к блоку кода. Слепо переводить переход на словарь (не задумываясь) - это действительно плохой совет.

  • Не использовать XML. Не имеет смысла, когда вырван из контекста. В контексте это означает, что не полагайтесь на XML, чтобы добавить гибкость. Java полагается на описание материала в XML; Файлы WSDL, например, повторяют информацию, которая очевидна при проверке кода. Python полагается на самоанализ вместо того, чтобы заново создавать все в XML.

    Но Python имеет превосходные библиотеки обработки XML. Несколько.

  • Getters и setters не являются обязательными в Python, они путями, что требуются в Java. Во-первых, у вас лучше самоанализ в Python, так что вам не нужны getters и setters, чтобы помочь сделать динамические объекты бобов. (Для этого используется collections.namedtuple ).

    Однако, у вас есть декоратор свойства , который объединит getters (и setters) в конструкцию, подобную атрибуту. Дело в том, что Python предпочитает обнажённые атрибуты; При необходимости, мы можем объединить getters и setters, чтобы появиться, как если бы есть простой атрибут.

    Кроме того, Python имеет классы дескрипторов, если свойства недостаточно сложны.

  • Дублирование кода часто является необходимым злом в Java (например, перегрузка метода), но не в Python. Правильно. Python использует необязательные аргументы вместо перегрузки метода.

    Пуля говорила о закрытии;это не так полезно, как простой совет разумно использовать значения аргументов по умолчанию.

-121--946254-

Лучший способ сделать это - использовать Where-Object для фильтрации и использования возвращенного массива.

Можно также использовать @ splat для передачи нескольких параметров команде (новая в V2). Если обновление невозможно (и если это возможно, просто соберите выходные данные Get-ChildItems (повторяя только один командлет) и выполните фильтрацию в общем коде).

Рабочей частью сценария становится:

$moreArgs = @{}
if (-not $NoRecurse) {
  $moreArgs["Recurse"] = $true
}

$filesToDelete = Get-ChildItem $BackupDir @moreArgs |
                 where-object {-not $_.PsIsContainer -and 
                               $_.LastWriteTime -lt $(Get-Date).AddDays($days) -and
                              -not $_.FullName.Contains($exclusion)}

В массивах PSH неизменяемы, их нельзя изменить, но очень легко создать новый (операторы, такие как + = на массивах фактически создают новый массив и возвращают его).

9
ответ дан 9 December 2019 в 20:42
поделиться

Я согласен с Ричардом, что здесь следует использовать Where-Object. Однако, это труднее читать. Что бы я предложил:

# get $filesToDelete and #exclusionList. In V2 use splatting as proposed by Richard.

$res = $filesToDelete | % {
    $file = $_
    $isExcluded = ($exclusionList | % { $file.FullName.Contains($_) } )
    if (!$isExcluded) { 
        $file
    }
}

#the  files are in $res

Также обратите внимание, что в общем случае невозможно выполнить итерацию над коллекцией и изменить ее. Вы получите исключение.

$a = New-Object System.Collections.ArrayList
$a.AddRange((1,2,3))
foreach($item in $a) { $a.Add($item*$item) }

An error occurred while enumerating through a collection:
At line:1 char:8
+ foreach <<<< ($item in $a) { $a.Add($item*$item) }
    + CategoryInfo          : InvalidOperation: (System.Collecti...numeratorSimple:ArrayListEnumeratorSimple) [], RuntimeException
    + FullyQualifiedErrorId : BadEnumeration
3
ответ дан 9 December 2019 в 20:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: