Предполагая, что список пар «ключ-значение» каждой строки содержит только значения без внедренного пробела или кавычек :
# Sample input line.
$line = 'ts=2019-01-16 network=1.1.1.1 system=irgendwas pid1=100 bugReq=dasf something=else maybe=this'
# Parse the line into key-value pairs and create a variable for each.
$i = 0
foreach ($keyOrValue in $line -split '[= ]') {
if ($i++ % 2 -eq 0) { $varName = $keyOrValue }
else { Set-Variable $varName $keyOrValue }
}
# $ts now contains '2019-01-16', $network '1.1.1.1', $system 'irgendwas', ...
Обратите внимание, как я немного изменил строку ввода образца для измененияpid
до pid1
, поскольку PowerShell не позволит вам создать переменную $PID
, поскольку она является автоматической переменной, отражающей PID (идентификатор процесса) текущего сеанса.
Другой вариант (который также позволил бы избежать конфликта имен переменных) - создать хеш-таблицу для каждой строки ввода:
# Sample input line.
$line = 'ts=2019-01-16 network=1.1.1.1 system=irgendwas pid=100 bugReq=dasf something=else maybe=this'
# Parse the line into key-value pairs and create a variable for each.
$htValues = @{} # Initialize the hashtable.
$i = 0
foreach ($keyOrValue in $line -split '[= ]') {
if ($i++ % 2 -eq 0) { $varName = $keyOrValue }
else { $htValues[$varName] = $keyOrValue }
}
# $htValues now has keys 'ts', 'network', 'system' with corresponding
# values, so you can access $htValues.ts to get '2019-01-16', for instance.
Этот подход имеет дополнительное преимущество:1018 * сбор хеш-таблиц, созданных для отдельных строк в общем массиве (например, $hashTableArray = foreach ($line in ...) { ... }
- хотя с очень большим файлом, который может быть недоступен.
Заимствованиеидея из ответа Lee_Dailey , вы можете альтернативно использовать командлет ConvertFrom-StringData
для создания хеш-таблицы, предварительно поместив каждую пару ключ-значение на свою собственную строку с помощью -replace
оператор:
$htValues = ConvertFrom-StringData ($line -replace ' ', "`n")
Предупреждение re ConvertFrom-StringData
заключается в том, что он интерпретирует \
символов.как начало escape-последовательности ;например, значение, такое как b\c
breaks команда:
Convertfrom-StringData 'a=b\c' # ERROR: "parsing 'b\c' - Missing control character."
С положительной стороны, использование ConvertFrom-StringData
на намного быстрее , чем ручноепарсинг с foreach
.
В качестве отступления: командлет PowerShell Get-Content
для чтения строк по одной (по умолчанию) удобен, но медленно .
Чтобы быстрее обработать строки (большого) текстового файла, используйте:
$file = 'file.txt'
foreach ($line in [System.IO.File]::ReadLines((Convert-Path $file))) {
# ...
}