Извлечение столбцов из текстового файла с помощью PowerShell

Мне нужно извлечь столбцы из текстового файла, описанного в этом посте:

Извлечение столбцов из текстового файла с использованием однострочного Perl : аналогично сокращению Unix

но я должен сделать это и в Windows Server 2008, на котором не установлен Perl. Как я могу сделать это с помощью PowerShell? Любые идеи или ресурсы? Я новичок в PowerShell...


person atricapilla    schedule 23.03.2010    source источник


Ответы (4)


Попробуй это:

Get-Content test.txt | Foreach {($_ -split '\s+',4)[0..2]}

И если вы хотите, чтобы данные в этих столбцах печатались в одной строке:

Get-Content test.txt | Foreach {"$(($_ -split '\s+',4)[0..2])"}

Обратите внимание, что для этого требуется PowerShell 2.0 для оператора -split. Кроме того, ,4 сообщает оператору разделения максимальное количество разделяемых строк, которые вы хотите, но имейте в виду, что последняя строка всегда будет содержать все объединенные дополнения.

Для столбцов с фиксированной шириной вот один из подходов для ширины столбца, равной 7 ($w=7):

$res = Get-Content test.txt | Foreach {
           $i=0;$w=7;$c=0; `
           while($i+$w -lt $_.length -and $c++ -lt 2) {
               $_.Substring($i,$w);$i=$i+$w-1}}

$res будет содержать каждый столбец для всех строк. Чтобы установить максимальное количество столбцов, измените $c++ -lt 2 с 2 на что-то другое. Вероятно, есть более элегантное решение, но сейчас нет времени его обдумывать. :-)

person Keith Hill    schedule 23.03.2010
comment
Спасибо, но это, кажется, не работает. Я запускаю PowerShell 2 и пытаюсь извлечь первые два столбца из моего файла .dat с фиксированной шириной (текстовый файл) - person atricapilla; 24.03.2010
comment
Вырезанный пример, на который вы ссылаетесь, использует разделитель пробелов и захватывает столбцы с 1 по 3. Если это не относится к вашему случаю, можете ли вы указать, каковы ваши требования? Звучит как фиксированная ширина столбца, а не с разделителями. Если да, то какова ширина столбца? - person Keith Hill; 24.03.2010
comment
Мои данные находятся в текстовом файле с фиксированной шириной (пробелы между ними). Я изменил ваш код и получил следующее: Get-Content text.txt | Foreach {$($_.split()[0..2])}. Это приближает меня, но это создает дополнительные разрывы строк между строками. - person atricapilla; 25.03.2010
comment
Убедитесь, что $OFS имеет значение $null или что-то вроде ' '. Также вы пробовали $_ -split '\s+',3? Это должно избавиться от лишних пустых записей. Принцип работы string.split заключается в том, что каждый последующий пробел после первого приводит к возврату дополнительной пустой строки. - person Keith Hill; 25.03.2010

Предполагая, что этот код разделен пробелами, он должен работать.

$fileName = "someFilePath.txt"
$columnToGet = 2
$columns = gc $fileName | 
   %{ $_.Split(" ",[StringSplitOptions]"RemoveEmptyEntries")[$columnToGet] }
person JaredPar    schedule 23.03.2010
comment
Я пробовал так C:› .\Extract_Two_Columns_From_Text_File.ps1 › twocols.dat Но ничего не напечатал? - person atricapilla; 24.03.2010

К обычному、

type foo.bar | % { $_.Split(" ") | select -first 3 }
person hoge    schedule 24.03.2010
comment
Если у вас есть несколько пробелов между столбцами (довольно часто), это приведет к появлению множества пустых записей. Вот почему Джаред использует значение перечисления [StringSplitOptions]::RemoveEmptyEntries. - person Keith Hill; 24.03.2010
comment
Да, это дает то же самое: Get-Content text.txt | Foreach {$($_.split()[0..2])}. - person atricapilla; 25.03.2010
comment
Я также пробовал это: Get-Content text.txt | Foreach {$($_.split( , [StringSplitOptions]::RemoveEmptyEntries))[0..2])}, но по-прежнему выдает эти пустые строки. - person atricapilla; 25.03.2010
comment
О, я вижу. это? gc R:\test.txt | % { $_ -split '\s+',4 | выбрать -f 3 } - person hoge; 25.03.2010

Попробуй это. Это поможет пропустить начальные строки, если вы хотите, извлечь/перебрать столбцы, отредактировать данные столбца и перестроить запись:

$header3 = @("Field_1","Field_2","Field_3","Field_4","Field_5")     

Import-Csv $fileName -Header $header3 -Delimiter "`t" | select -skip 3 | Foreach-Object {

    $record = $indexName 
    foreach ($property in $_.PSObject.Properties){

        #doSomething $property.Name, $property.Value

            if($property.Name -like '*CUSIP*'){

                $record = $record + "," + '"' + $property.Value + '"' 
            }
            else{
                $record = $record + "," + $property.Value 
            }                           
    }               

        $array.add($record) | out-null  
        #write-host $record                         
}
person user3100105    schedule 22.09.2017