Что эквивалентно команде * Nix 'cut' в Powershell?

У меня есть следующий контент в файле конфигурации (sample.cfg),

Time_Zone_Variance(Mins):300
Alert_Interval(Mins):2
Server:10.0.0.9
Port:1840

Я пытаюсь сохранить каждое значение после :, используя split в PowerShell. но я не могу произвести требуемый вывод.

Может ли кто-нибудь сказать мне, как использовать PowerShell split для вышеуказанной проблемы?

Ответ 1

Вы можете прочитать содержимое файла с помощью Get-Content, затем проложить каждую строку через ForEach-Object, а затем использовать команду split в каждой строке, взяв второй элемент в массиве следующим образом:

$filename = "sample.cfg"

Get-Content $filename | ForEach-Object {
    $_.split(":")[1]
}

Выход

300
2
10.0.0.9
1840

Обновление

Я предпочитаю подход @AnsgarWiechers, но если вам действительно нужны конкретные именованные значения, вы можете создать хеш-таблицу и заменить имя на значение:

$configValues = @{
    hour    = "Time_Zone_Variance(Mins)"
    min     = "Alert_Interval(Mins)"
    server  = "Server"
    port    = "Port"
}

Get-Content $filename | ForEach-Object {

    # Courtesy of Ansgar Wiechers
    $key, $value = $_ -split ':', 2

    foreach($configValuesKey in $($configValues.keys)) {
        if ($configValues[$configValuesKey] -eq $key)
        {
            $configValues[$configValuesKey] = $value
        }
    }
}

write-host "`nAll Values:"
$configValues
write-host "`nIndividual value:"
$configValues.port

Выход

All Values:

Name                           Value                                                                                             
----                           -----                                                                                             
port                           1840                                                                                              
min                            2                                                                                                 
server                         10.0.0.9                                                                                          
hour                           300                                                                                               

Individual value:
1840

Ответ 2

Я предполагаю, что вы не хотите просто разбивать строки, но на самом деле создавать пары ключ/значение. Это может быть достигнуто следующим образом:

$config = @{}
Get-Content 'C:\path\to\sample.cfg' | % {
  $key, $value = $_ -split ':', 2
  $config[$key] = $value
}

Вы также можете использовать командлет ConvertFrom-StringData:

Get-Content 'C:\path\to\sample.cfg' | % {
  ConvertFrom-StringData ($_ -replace ':','=')
}

Операция -replace необходима, потому что ConvertFrom-StringData ожидает, что ключ и значение будут разделены =. Если вы можете изменить разделитель в файле конфигурации от : до =, вы можете использовать ConvertFrom-StringData $_ без замены.

Ответ 3

Как это?

function cut {
  param(
    [Parameter(ValueFromPipeline=$True)] [string]$inputobject,
    [string]$delimiter='\s+',
    [string[]]$field
  )

  process {
    if ($field -eq $null) { $inputobject -split $delimiter } else {
      ($inputobject -split $delimiter)[$field] }
  }
}


PS C:\> 'hi:there' | cut -f 0 -d :
hi

PS C:\> 'hi:there' | cut -f 1 -d :
there

PS C:\> 'hi:there' | cut -f 0,1 -d :
hi
there

PS C:\> 'hi:::there' | cut -f 0 -d :+
hi

PS C:\> 'hi   there' | cut
hi
there

Ответ 4

Для более краткого синтаксиса это также поможет:

((Get-Content "your-file.txt") -Split ":")[1]

Таким образом, хитрость в использовании метода -Split заключается в том, чтобы объект String возвращался Get-Content (на самом деле также можно использовать псевдоним cat), а из полученного объекта String[] можно использовать скобки для извлечения элемента n th.

Примечание: Использование -Split без скобок вокруг Get-Content не будет работать, поскольку -Split не является именем параметра для этой команды... 🤷‍♂️