Как прочитать конкретное значение строки с аргументом с помощью PowerShell?

#powershell #text-parsing

#powershell #синтаксический анализ текста

Вопрос:

У меня есть файл с этим форматом.

 English
Name
    Gerry
Class
    Elementry
ID Number
    0812RX
Gender
    *Male
     Female
Address
     St.Joseph Rd.78
Member Name
     Jack
  

Структура этого файла такова: значение Name , есть один enter и один tab , а затем значение Gerry

Я хочу прочитать значение каждого элемента. Я попробовал этот код.

 Param(
  [parameter(mandatory=$true)][string]$FilePath, $Key
)

$FileContent = Get-Content $FilePath | Where-Object{"^($Key)","`$1$Value"}
$FileContent
  

Мое ожидание, когда я выполняю эту команду

 powershell.ps1 -FilePath file.txt -Key Name
  

Он вернет : Gerry

Пожалуйста, кто-нибудь подскажет мне идею. Спасибо

Комментарии:

1. Файл не похож на стандартизированную структуру. Вам придется разобрать это самостоятельно. Где вы берете этот файл? Может ли программа / процесс, из которого вы получаете этот файл, предоставлять данные в стандартном формате файла, таком как CSV, JSON или XML?

Ответ №1:

Лучший вариант — использовать switch инструкцию с -File параметром:

 $found = $false
$value = switch -File file.txt {
  'Name' { $found = $true }
  default { if ($found) { $_.Substring(1); break } }
}
  

В вашем примере ввода $value должно тогда содержаться Gerry .

$found устанавливается равным, $true как только 'Name' находится в отдельной строке; в default блоке, который выполняется для всех других строк, затем возвращается следующая строка, лишенная своего начального символа (табуляции).

Завернутый в скрипт с параметрами, смоделированный здесь с помощью блока скрипта для краткости:

 # Create a sample file; "`t" creates a tab char.
@"
Name
`tGerry
Class
`tElementary
ID Number
`t0812RX
"@ > file.txt

# Script block that simulates a script file.
amp; {

  param(
    [Parameter(Mandatory)] [string] $FilePath,
    [Parameter(Mandatory)] [string] $Key
  )

  $found = $false
  switch -File $FilePath { 
    $Key { $found = $true }
    default { if ($found) { return $_.Substring(1) } }
  }

} -FilePath file.txt -Key Name
  

Вышеуказанные результаты Gerry .

Обратите внимание, что если в имени вашего ключа есть пробелы, вы должны передать его скрипту в кавычках; например:

 ... -FilePath file.txt  -Key 'ID Number'
  

Комментарии:

1. пожалуйста, еще один вопрос, я хотел бы установить значение в качестве переменной, я пробовал это $GetValue = switch -File $FilePath {$Key { $found = $true } default { if ($found) { return $_.Substring(1) } }} $test = $GetValue "ok" $test , но я не могу получить значение @mklementO

Ответ №2:

Когда вы это делаете Get-Content , файл поступает в виде массива строк, на которые вы можете ссылаться.

Предполагается, что ваши файлы имеют согласованный формат — что в них одинаковое количество строк, а строки соответствуют полям, указанным в вашем примере. Если нет, то можно что-то сделать с регулярными выражениями, но мы не будем сейчас вдаваться в это.

 $file = (get-content c:tempmyfile.txt).trim()
$lang = $file[0]
$name = $file[3]
$class = $file[5]
$idNo = $file[7]
if ($file[9] -match '`*') {$gender = "Male"}
if ($file[10] -match '`*') {$gender = "Female"}
$address = $file[12]
  

Затем вы можете присвоить записанные значения объекту PSCustomObject или хэш-таблице. На самом деле, проще всего просто выполнять это одновременно.

 $student= [PsCustomObject]@{
    Lang = $file[0]
    Name = $file[3]
    Class = $file[5]
    ...
}
  

Я оставлю вывод атрибутов объекта описанным вами способом как упражнение для вашего собственного удовольствия!

Комментарии:

1. Я не хочу идентифицировать его, указывая номер индекса, потому что позиция иногда отличается.