2016-04-20 4 views
-1

У меня есть сценарий ниже Powershell, который я вытягиваю только из первых двух столбцов из-за того, что не смог правильно распределить остальные. Я бы хотел, чтобы мой импорт всегда делился на 7 столбцов с включенным каждым набором данных.Как разбить на основе нескольких заданных разделителей

Мой текущий PS Сценарий:

$serverNames = Get-Content "C$\app\test\ServerList2.txt" 
$ServerList = @() 

foreach ($serverName in $serverNames) { 
    $ServerList += Import-Csv "C$\app\test\$serverName.txt" -Header "Extension","Server IP","TRUE","NIC","Comments","PCName" | 
    Select-Object *, @{n='Server Name';e={$serverName}} 
} 

$ServerList 

Мои два Примеры файлов: Пример 1:

; sample entries 
; StationID, MAC Address,  Recording Enabled 
; AddressType = MAC 
; 5201,  00.0d.29.0b.cd.34, TRUE 
; 5202,  00.0D.29.0B.D9.30, TRUE 


; StationID, IP Address,  Recording Enabled 
AddressType = IP4 

10000, 192.168.1.137, TRUE, 1   ; My Comments  PCName 
10001, 192.168.1.28, TRUE   ;My Comments 
10003, 192.168.1.63, TRUE,2   ; My Comments  PCName 

Пример 2:

; sample entries 
; StationID, MAC Address,  Recording Enabled 
; AddressType = MAC 
; 5201,  00.0d.29.0b.cd.34, TRUE 
; 5202,  00.0D.29.0B.D9.30, TRUE 


; StationID, IP Address,  Recording Enabled 
AddressType = IP4 

10010, 192.168.1.29, TRUE,1   ; My Comments 4 
10040, 192.168.1.7, TRUE   ; My Comments 5  PCName 
10100, 192.168.1.14, TRUE,2   ; My Comments 6 PCName 

данных я обеспокоен является просто строки, начинающиеся с цифр. Как вы можете сказать, хотя не все строки имеют одинаковые разделители, которые добавляют к сложности. Я пытаюсь сделать вывод таким, как показано ниже.

Extension IP Address  TRUE NIC Comments  PC Name Server Name 
10000  192.168.1.137 TRUE 1  My Comments 1 PCName1 Server1 
10001  192.168.1.28 TRUE   My Comments 2    Server1 
10003  192.168.1.63 TRUE 2  My Comments 3 PCName3 Server1 
10010  192.168.1.29 TRUE 1  My Comments 4    Server2 
10040  192.168.1.7  TRUE   My Comments 5 PCName5 Server2 
10100  192.168.1.14 TRUE 2  My Comments 6 PCName6 Server2 

ответ

2

Import-CSV (и CSV-формат, в целом) использует один разделитель. Если ваши файлы имеют несколько разделителей и «необязательные» поля (но не нулевые значения, но отсутствуют значения), то это не CSV. Лучший способ - создать собственный парсер с использованием регулярного выражения. Ex.

$regex = '^(?<Extension>.+?),\s?(?<IPAddress>.+?),\s+(?<TRUE>\w+?)(?:,\s?(?<NIC>\d))?\s+?;\s?(?<Comments>.+?)(?:\s{2,}(?<PCName>\w+))?$' 

$serverNames = Get-Content "C$\app\test\ServerList2.txt" 
$ServerList = @() 

foreach ($serverName in $serverNames) { 
    Get-Content -Path "C$\app\test\$serverName.txt" | ForEach-Object { 
     if($_ -match $regex) { 
      $ServerList += New-Object -TypeName psobject -Property $Matches | 
      Select-Object -Property "Extension","IPAddress","TRUE","NIC","Comments","PCName", @{n='Server Name';e={$serverName}} 
     } 
    } 
} 

$ServerList 

Demo и объяснение регулярных выражений: Regex101

+0

большое спасибо. и спасибо за сайт regex, он действительно объясняет, как работает вся последовательность, чего я уже не видел. –

+0

Вопрос. Я запускал это, и он отлично работает на моих файлах, однако я столкнулся с небольшой проблемой, по-видимому, некоторые сайты будут помещать свои данные в этот формат, в котором не работает соответствующее регулярное выражение. 45239, 10.1.11.111, TRUE \t \t \t; Мои комментарии \t \t Имя компьютера \t \t Агент. У них есть пробел и вкладка после комментариев, что заставляет и комментарий, и имя ПК переходить в одну строку. Я также хотел бы игнорировать агент после имени ПК. Мысли? –

+0

Нет проблем. Я действительно очень доволен решением. Не думаю, что я когда-либо использовал именованные группы в качестве динамического анализа текста. На протяжении многих лет он мог бы сэкономить мне много строк кода. :-) –

Смежные вопросы