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

Day-Hour, 08188, 0, 08188, 1, (indicating the time is year 2008, julian day 188, between hour0 and hour1)
Receptor, A, (actual data begins)
1, 2, 3, 4,
5, 6, 7, 8,
Receptor, B,
1, 2, 3, 4,
5, 6, 7, 8,
... (continue data for a total of 22 receptors, each receptor has 8 data values)

Day-Hour, 08188, 1, 08188, 2,
Receptor, A,
1, 2, 3, 4,
5, 6, 7, 8,
Receptor, B,
1, 2, 3, 4,
5, 6, 7, 8,
... (continue data for a total of 22 receptors, each receptor has 8 data values, but this is for hours 1 to 2)

...... (continue the same previous pattern for a total of 24 times)

Я бы хотел переформатировать его так:

day, time, receptor, data1, data2, data3, ....data8  (header)
08188, 0, A, 1, 2, 3, 4, 5, 6, 7, 8
08188, 0, B, 1, 2, 3, 4, 5, 6, 7, 8
... (repeat the same hour for all 22 receptor sites)
08188, 1, A, 1, 2, 3, 4, 5, 6, 7, 8
08188, 1, B, 1, 2, 3, 4, 5, 6, 7, 8 
...(repeat the same hour for all 22 receptor sites)
...
...(repeat the same order 24 times)

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

(example steps:)
step1:  $ grep -v "Day-Hour" infile.txt > temp1.txt  # remove all Day-Hour lines, 
                                                     # as I know the order of the data
step2:  $ sed '/^$/d' temp1.txt > temp2.txt  # remove empty lines
step3:  $ awk 'ORS=NR%3" ":"\n"' temp2.txt > temp3.txt  #concatenate every 3 lines
step4:  $ (create a file, e.g. daytime.txt, with 2 fields (day and hour) with following content)
         08188, 0,
         (repeat 22 times)
         08188, 1,
         (repeat 22 times)
         .... (continue through hour 23)
step5:  $ paste daytime.txt temp3.txt > final.txt
-2
Jung 6 Сен 2014 в 02:34
Вы уверены, что ваш столбец time заполнен правильно? Первая строка 08188, 0, 08188, 1 дает 0 время как для A, так и для B? Я бы порекомендовал лучший выбор выборочных данных.
 – 
jaypal singh
6 Сен 2014 в 02:46
1
Да, вы можете добиться этого с помощью команд awk и sed. На самом деле, просто awk должно быть достаточно. Прочтите справочную страницу для более подробной информации.
 – 
Sneftel
6 Сен 2014 в 03:02
Это простая работа и для perl.
 – 
clt60
6 Сен 2014 в 03:09
Извините, я не ясно выразился в своем первоначальном посте о том, чего я действительно хочу достичь. Я отредактировал вопрос, и, надеюсь, он вам более понятен. Спасибо!
 – 
Jung
6 Сен 2014 в 10:00

2 ответа

Лучший ответ

Это может помочь:

cat file
Day-Hour, 08188, 0, 08188, 1
Receptor, A,
1, 2, 3, 4,
5, 6, 7, 8,
Receptor, B,
11, 12, 13, 14,
15, 16, 17, 18,
Receptor, C,
21, 22, 23, 24,
25, 26, 27, 28,

Day-Hour, 08188, 1, 08188, 2
Receptor, A,
1, 2, 3, 4,
5, 6, 7, 8,
Receptor, B,
1, 2, 3, 4,
5, 6, 7, 8,
awk -v RS= -v OFS=", " -F", *|\n" 'BEGIN {print "day, time, receptor, data1, data2, data3,....data8"} {for (i=7;i<=NF;i+=13) print $2,$3,$i,$(i+2),$(i+3),$(i+4),$(i+5),$(i+7),$(i+8),$(i+9),$(i+10)}' file
day, time, receptor, data1, data2, data3,....data8
08188, 0, A, 1, 2, 3, 4, 5, 6, 7, 8
08188, 0, B, 11, 12, 13, 14, 15, 16, 17, 18
08188, 0, C, 21, 22, 23, 24, 25, 26, 27, 28
08188, 1, A, 1, 2, 3, 4, 5, 6, 7, 8
08188, 1, B, 1, 2, 3, 4, 5, 6, 7, 8

Это напечатает все Receptor, если это 1 или 22.

0
Jotne 6 Сен 2014 в 10:48
Похоже, я случайно пропустил дополнительное «,» в конце строки Day-Hour. Должно быть так: «День-Час, 08188, 0, 08188, 1» в первой строке. И это, кажется, выводит все из строя с вашим кодом. Прости за это. Любое предложение?
 – 
Jung
6 Сен 2014 в 12:50
Добавить отсутствующий , очень просто. Вы должны быть в состоянии исправить это. Мой код отлично работает с вашими данными. Если он не работает с другими данными, вам нужно опубликовать его, чтобы увидеть, что не так.
 – 
Jotne
6 Сен 2014 в 18:48

Это объединит их:

sed 's/$/,/;N;N;N;N;N;N;N; s/\n/ /g' foo.txt

В это:

День-час, 08188, 0, 08188, 1, Рецептор, A, 1, 2, 3, 4, 5, 6, 7, 8, Рецептор, B, 1, 2, 3, 4, 5, 6, 7, 8, день-час, 08188, 1, 08188, 2, рецептор, A, 1, 2, 3, 4, 5, 6, 7, 8, рецептор, B, 1, 2, 3, 4, 5, 6, 7, 8,

Потом поленился переупаковывать:

... | awk '{ $1 = ""; $4 = ""; $5 = ""; print }' | sed -e 's/ \(.*\)  Receptor, \(A,.*\)Receptor, \(B, .*\)/\1\2\n\1\3/'

Что произвело желаемый результат в моей системе.

0
Alain Collins 6 Сен 2014 в 03:35