Почему это не считается правильным | PowerShell

Прямо сейчас у меня есть файл CSV, который содержит более 3800 записей. Этот файл содержит список имен серверов, за которым следует аббревиатура, указывающая, является ли сервер сервером Windows, сервером Linux и т. д. Файл также содержит комментарии или документацию, где каждая строка начинается с символа «#», что означает, что это комментарий. На данный момент у меня есть следующее.

$file = Get-Content .\allsystems.csv
$arraysplit = @()
$arrayfinal = @()
[int]$windows = 0

foreach ($thing in $file){
    if ($thing.StartsWith("#")) {
        continue
        }
    else {
        $arraysplit = $thing.Split(":")
        $arrayfinal = @($arraysplit[0], $arraysplit[1])
    }
}

foreach ($item in $arrayfinal){
    if ($item[1] -contains 'NT'){
        $windows++
    }
    else {
        continue
    }
}
$windows

Цель этого сценария - подсчитать общее количество серверов Windows. Моя проблема в том, что первый блок «foreach» работает нормально, но второй приводит к тому, что «$ Windows» становится 0. Честно говоря, я не уверен, почему это не работает. Вот две примерные строки данных:

example:LNX

example2:NT
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
83
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий
$arrayfinal = @($arraysplit[0], $arraysplit[1])

Это заменяет массив при каждом запуске.

Замена его на += дала еще одну проблему. Он просто добавлял каждый отдельный элемент. Я использовал информацию из этого поста, чтобы исправить это, как бы форсируя 2d-массив: Как создать массив массивов в PowerShell?.

$file = Get-Content .\allsystems.csv
$arraysplit = @()
$arrayfinal = @()
[int]$windows = 0

foreach ($thing in $file){
    if ($thing.StartsWith("#")) {
        continue
        }
    else {
        $arraysplit = $thing.Split(":")
        $arrayfinal += ,$arraysplit
    }
}

foreach ($item in $arrayfinal){
    if ($item[1] -contains 'NT'){
        $windows++
    }
    else {
        continue
    }
}
$windows

1

Я также изменил файл и добавил больше экземпляров NT и другого случайного мусора. Кажется, все работает нормально.

Я бы не стал делать еще один цикл ForEach для увеличения количества экземпляров. Ваш $ arrayfinal также перезаписывается каждый раз, поэтому я использовал ArrayList.

$file = Get-Content "E:\Code\PS\myPS\2018\Jun\12\allSystems.csv"
$arrayFinal = New-Object System.Collections.ArrayList($null)

foreach ($thing in $file){
    if ($thing.StartsWith("#")) {
        continue
        }
    else {
        $arraysplit = $thing -split ":"
        if ($arraysplit[1] -match "NT" -or $arraysplit[1] -match "Windows")
        {
            $arrayfinal.Add($arraysplit[1]) | Out-Null
        }
    }
}

Write-Host "Entries with 'NT' or 'Windows' $($arrayFinal.Count)"

Я не уверен, хотите ли вы сохранить 'Example', 'example2' ... поэтому я пропустил добавление их в arrayfinal, предполагая, что цель состоит в том, чтобы подсчитать появления "NT" или "Windows"

если цель состоит в том, чтобы подсчитать серверы Windows, зачем вам массив?

ты не можешь просто сказать что-нибудь вроде

foreach ($thing in $file)
{
    if ($thing -notmatch "^#" -and $thing -match "NT") { $windows++ }
}

Дальнейшее упрощение: -cmatch '^[^#].*?NT'

Maximilian Burszley 12.06.2018 00:09

The goal of this script is to count the total number of Windows servers.

Я бы посоветовал простой способ: использовать специально созданные для этого командлеты.

$csv = Get-Content -Path .\file.csv |
    Where-Object { -not $_.StartsWith('#') } |
    ConvertFrom-Csv

@($csv.servertype).Where({ $_.Equals('NT') }).Count

# Compatibility mode:
# ($csv.servertype | Where-Object { $_.Equals('NT') }).Count

Замените servertype и 'NT' тем, что называется заголовком / значением.

Другие вопросы по теме