Bash - разбить текстовый файл по столбцам по позициям / индексам - PullRequest
0 голосов
/ 09 мая 2019

У меня есть текстовый файл со структурой, похожей на:

2013-11-22 eps Ind      2400000.23551544    100.    
2013-11-22 eps Ind      2400000.23551544    100.    
2013-11-22 eps Ind      2400000.23551544    100.    
2013-11-22 HD 217987    2400000.23551544    900.        
2013-11-22 TOI-134      2400000.23551544    900.    
2013-11-22 tau Cet      2400000.23551544    60.     
2013-11-22 BD+01   316  2400000.23551544    300.    
2013-11-22 BD+01   316  2400000.23551544    300.    
2013-11-22 BD+01   316  2400000.23551544    300.    
2013-11-22 BD+01   316  2400000.23551544    300. 

и мне нужно извлечь его с помощью bash. Основная проблема, с которой я столкнулся, заключается в том, что хотя столбцы разделены табуляцией, имена в столбцах могут иметь символы табуляции или пробелы, поэтому при использовании awk в некоторых случаях я получаю неправильные столбцы. Как разделить текстовый файл по столбцам, но по индексу? Все столбцы имеют одинаковую ширину в символах - учитывая, что пробел - это символ. Каждый столбец имеет разную ширину.

Обратите внимание, что eps Ind, HD 217987 и BD+01 316 находятся в одном столбце.

Спасибо Хорхе

Ответы [ 3 ]

2 голосов
/ 09 мая 2019

Если ваши входные данные действительно являются полями фиксированной ширины, как вы сказали (я предполагаю, что вы имели в виду all columns have the same width in characters, а не то, что все поля имеют одинаковую ширину внутри друг друга и внутри всех строк), тогда используйте GNU awkдля полей:

$ cat tst.awk
BEGIN {
    FIELDWIDTHS = "11 13 20 *"
    OFS = ","
}
{
    for (i=1; i<=NF; i++) {
        gsub(/^\s+|\s+$/,"",$i)
        printf "[%d]=\"%s\"%s", i, $i, (i<NF ? OFS : ORS)
    }
}

$ awk -f tst.awk file
[1]="2013-11-22",[2]="eps Ind",[3]="2400000.23551544",[4]="100."
[1]="2013-11-22",[2]="eps Ind",[3]="2400000.23551544",[4]="100."
[1]="2013-11-22",[2]="eps Ind",[3]="2400000.23551544",[4]="100."
[1]="2013-11-22",[2]="HD 217987",[3]="2400000.23551544",[4]="900."
[1]="2013-11-22",[2]="TOI-134",[3]="2400000.23551544",[4]="900."
[1]="2013-11-22",[2]="tau Cet",[3]="2400000.23551544",[4]="60."
[1]="2013-11-22",[2]="BD+01   316",[3]="2400000.23551544",[4]="300."
[1]="2013-11-22",[2]="BD+01   316",[3]="2400000.23551544",[4]="300."
[1]="2013-11-22",[2]="BD+01   316",[3]="2400000.23551544",[4]="300."
[1]="2013-11-22",[2]="BD+01   316",[3]="2400000.23551544",[4]="300."
1 голос
/ 09 мая 2019

Я рекомендую использовать инструмент cut для разделения данных на столбцы.

РЕДАКТИРОВАТЬ: Если у вас есть возможные вкладки в пределах столбцов, но фиксированное поле с, используйте cut с позициями символов:

cut -c 12-24,45-50 file.txt
0 голосов
/ 09 мая 2019

Вот другой подход, который использует Python. Малоизвестный секрет - Python может быть выдающимся инструментом для обработки текста.

#!/usr/bin/env python
import csv
import fileinput
import sys

# Write comma-separated values (CSV) to standard output
writer = csv.writer(sys.stdout)

# For each line of the input, split into columns,
# strip off the leading and trailing white spaces,
# then write the output
for line in fileinput.input():
    columns = [
            line[:11].strip(),    # Index 0 to 10
            line[11:24].strip(),  # Index 11 to 23
            line[24:44].strip(),  # Index 24 to 43
            line[44:].strip()     # The rest
    ]
    writer.writerow(columns)

Вызов сценария

python script.py data.txt

выход

2013-11-22,eps Ind,2400000.23551544,100.
2013-11-22,eps Ind,2400000.23551544,100.
2013-11-22,eps Ind,2400000.23551544,100.
2013-11-22,HD 217987,2400000.23551544,900.
2013-11-22,TOI-134,2400000.23551544,900.
2013-11-22,tau Cet,2400000.23551544,60.
2013-11-22,BD+01   316,2400000.23551544,300.
2013-11-22,BD+01   316,2400000.23551544,300.
2013-11-22,BD+01   316,2400000.23551544,300.
2013-11-22,BD+01   316,2400000.23551544,300.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...