Удалить заголовок из текстового файла с разделителями

У меня есть текстовые файлы, в которых данные разделены косой чертой. Его достаточно просто импортировать и передать в пользовательский объект, но файлы имеют заголовки, содержащие разделитель. Пример ниже:

HEADER LINE 1/INFO/MOREINFO
HEADER LINE 2/INFO/MOREINFO
HEADER LINE 3/INFO/MOREINFO
HEADER LINE 4/INFO/MOREINFO
HEADER LINE 5/INFO/MOREINFO
HEADER LINE 6/INFO/MOREINFO
HEADER LINE 7/INFO/MOREINFO

LINE1A/1B///1E/1F/1G/1H
LINE2A/2B/2C//2E//2G/2H
...
/END/

В строках «LINE1A», «LINE1B» и т. д. есть данные, которые мне нужно импортировать. Использование -split '/' позволяет мне разделить все на красивый массив, но только если этого заголовка там нет.

$data = (Get-Content text.txt).Replace('Line', '/Line') -split('/')

Если заголовок присутствует, первые элементы в массиве $data включают заголовок.

Я пробовал трюки со строками, но, к сожалению, текст заголовка не соответствует форме одного файла к другому. Количество строк (всегда 7) и количество косых черт (2 на строку заголовка) одинаковы, но текст в каждой строке различается.

Поскольку Get-Content создает массивы, разделенные возвратом каретки (поправьте меня, если я ошибаюсь), я мог бы просто удалить первые 7 элементов массива. Этот код работает для удаления первого элемента:

$data = (Get-Content text.txt) 
$data = $data | Where-Object {$_ -ne $data[0]}

Но это не очень масштабируемо. Я не хочу зацикливать команду 7 раз. Есть ли более элегантный способ сделать это? Может быть, какое-то регулярное выражение, основанное на возврате каретки и/или косой черте?


person Bagheera    schedule 22.08.2017    source источник


Ответы (3)


Здесь всё просто, используйте командлет Select-Object, чтобы пропустить первые 7 строк!

$data = (Get-Content text.txt | Select -Skip 7).replace('Line','/Line') -split('/')

Если в строке 8 есть пустая строка, вы можете вместо этого пропустить первые 8 строк.

person TheMadTechnician    schedule 22.08.2017
comment
Возможно, придется иметь дело с этой последней строкой. - person Matt; 22.08.2017
comment
Он сказал, что его процесс работает, если у него нет строк заголовков, поэтому я решил, что можно с уверенностью предположить, что у него уже есть что-то, что нужно сделать с этой последней строкой. - person TheMadTechnician; 22.08.2017
comment
Спасибо. Я знал, что это будет что-то простое. - person Bagheera; 23.08.2017

Как только вы прочитаете файл в массив $data, просто скопируйте все, кроме первых 7 строк данных, в новый массив.

 $data2 = $data[7..($data.length-1)]

а потом работать с $data2.

person Jeff Zeitlin    schedule 22.08.2017

Если числам и линиям нельзя доверять, я предлагаю что-то другое. Позволяет отфильтровать все строки, начинающиеся с заголовка или конца, и отфильтровать пустые строки. Затем давайте создадим пользовательские объекты так же, как Import-CSV

$fileContents = Get-Content "file"
$csv = $fileContents | Where-Object{![string]::IsNullOrWhiteSpace($_) -and $_ -notmatch "^(HEADER|/END/)"}
# Determine the number of headers from the file 'CSV' line
$numberOfHeaders = $csv[0].split("/").Count
ConvertFrom-Csv $csv -Header (1..$numberOfHeaders|ForEach-Object{"LINE $_"}) -Delimiter "/"

Это работает с использованием ваших выборочных входных данных, игнорируя только многоточие. Итак, теперь у вас есть эквивалент того, как будет выглядеть правильный CSV при использовании IMport-CSV. Заголовок был моим предположением. Не потребуется многого, чтобы изменить это, если возникнут другие потребности.

LINE 1 LINE 2 LINE 3 LINE 4 LINE 5 LINE 6 LINE 7 LINE 8
------ ------ ------ ------ ------ ------ ------ ------
1A     1B                   1E     1F     1G     1H    
2A     2B     2C            2E            2G     2H    

Если вам не нужна ведущая "LINE" в данных, то перед преобразованием это можно исправить с помощью простого конвейера.

ForEach-Object{$_ -replace "^LINE"}

Если хотите убрать из шапки то поиграйтесь с этим 1..$numberOfHeaders|ForEach-Object{"LINE $_"}. Так что, если вас устраивает только пронумерованный столбец, вы можете просто оставить его на 1..$numberOfHeaders

person Matt    schedule 22.08.2017