Регулируемые строки и столбцы из одного столбца в несколько столбцов AWK

У меня есть входные данные, которые выглядят так в формате «мм/гггг, данные»:

Location 1
08/2012, 44.1
09/2012, 34.2
10/2012, 24.3
11/2012, 14.4
12/2012, 04.5
01/2013, 14.6
02/2013, 24.7
Location 2
08/2012, 33.1
09/2012, 44.2
10/2012, 55.3
11/2012, 66.4
12/2012, 77.5
01/2013, 88.6
02/2013, 11.7
Location 3
08/2012, 35.1
09/2012, 45.2
10/2012, 55.3
11/2012, 66.4
12/2012, 77.5
01/2013, 71.6 
02/2013, 19.7
Location 4
etc
etc

и я использую awk-скрипт, который таков:

awk '}printf (NR %276 == 0)? $0"\n" : $0"\t" }' inputfile (я использую NR%276, потому что это длина столбца для каждого нового повторяющегося столбца или "местоположение" в исходных данных, показанных в части выше). Awk может просто разделить фрагменты данных одного столбца из «Местоположения X» в «Местоположение Y» в n столбцах вывода?

Я получаю вывод, но неправильно запускать вывод из входного файла с одним столбцом по горизонтали в виде переноса текста или «змеиной» следующим образом: местоположение 1 мм/гггг, данные1 данные2 и т. д. Местоположение 2 мм/гггг, данные1 данные2 и т. д. 3 мм/гггг, данные1 данные2 и т.д.

Вместо этого мне нужно, чтобы мои выходные данные напоминали эти, но для 276 строк и около 150 столбцов/местоположений или для последнего отдельного столбца данных «Местоположение» из 276 строк во входном файле (укороченный пример показан выше). Было бы полезно увеличить количество строк до 277, например, для 03/2013 или до >150 местоположений.

Location 1        Location 2        Location 3
08/2012, 44.1     08/2012, 33.1     08/2012, 35.1
09/2012, 34.2     09/2012, 44.2     09/2012, 45.2
10/2012, 24.3     10/2012, 55.3     10/2012, 55.3
11/2012, 14.4     11/2012, 66.4     11/2012, 66.4
12/2012, 04.5     12/2012, 77.5     12/2012, 77.5
01/2013, 14.6     01/2013, 88.6     01/2013, 71.6
02/2013, 24.7     02/2013, 11.7     02/2013, 19.7

Спасибо!!


awk
person user2100039    schedule 18.03.2013    source источник


Ответы (3)


Другой awk, который вы могли бы попробовать:

awk '!/^[0-9]/{n=0} {n++; A[n]=A[n] (A[n]?OFS:x) $0} END{for(i=1; i<=n; i++) print A[i]}' OFS='\t' file

Чтобы распечатать только второй столбец в каждом месте:

awk '!/^[0-9]/{n=0} {n++; A[n]=A[n] (A[n]?OFS:x) $2} END{for(i=1; i<=n; i++) print A[i]}' OFS='\t' file
person Scrutinizer    schedule 18.03.2013
comment
хорошо, это работает. мне нужно выяснить, как печатать только 2 доллара или второй столбец для каждого местоположения или заголовка столбца. Есть идеи? на данный момент он печатает и 1, и 2 доллара. Спасибо, - person user2100039; 19.03.2013
comment
@user2100039: добавлено быстрое исправление. - person Scrutinizer; 19.03.2013

попробуйте этот однострочный:

 awk '/^Location/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file

примечание

  • строка выше преобразует ваш ввод с одним столбцом в вывод с тремя столбцами, не обрабатывала ваши 276 rows вещи. (Я не думаю, что нам нужно делать этот расчет.)
  • в выводе столбцы разделены tab.
  • строка и столбец не жестко закодированы, вы можете проверить свои реальные данные

тест с вашими данными:

kent$  awk '/^Location/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file      
Location 1      Location 2      Location 3
08/2012, 44.1   08/2012, 33.1   08/2012, 35.1
09/2012, 34.2   09/2012, 44.2   09/2012, 45.2
10/2012, 24.3   10/2012, 55.3   10/2012, 55.3
11/2012, 14.4   11/2012, 66.4   11/2012, 66.4
12/2012, 04.5   12/2012, 77.5   12/2012, 77.5
01/2013, 14.6   01/2013, 88.6   01/2013, 71.6 
02/2013, 24.7   02/2013, 11.7   02/2013, 19.7

EDIT для комментариев

 awk '!/^[0-9]/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=277&&m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file 
  • приведенная выше строка не будет соответствовать жестко запрограммированному «Местоположению», но для нечисловых заголовков (работает и для «местоположений»)
  • 276, 277 Я не знаю, что это значит. но приведенный выше однострочный текст будет для каждого блока (местоположение в вашем примере) печатать максимум 276 строк. если номер строки меньше 276, просто напечатайте фактическое количество строк.

Вы можете немного изменить однострочник, чтобы он соответствовал вашим потребностям.

Удачи.

person Kent    schedule 18.03.2013
comment
Извините, заголовок столбца Location 1 и т. д. предназначен для этого примера, но на самом деле это имена, которые меняются, поэтому Location никогда не появляется во входном файле. Может ли он вместо этого просто искать строку любой длины? - person user2100039; 18.03.2013
comment
во входном файле строки данных = 276, включая заголовок, строки = 277. еще раз спасибо- - person user2100039; 18.03.2013
comment
@user2100039 user2100039 так что бы это было место в ваших реальных данных? по какому-то шаблону? во всяком случае, я думаю, что моя острота поможет вам начать. - person Kent; 18.03.2013
comment
такие имена, как Eagle, Westridge, MesaTop и т. д., уникальны для каждого фрагмента заголовка + 276 строк данных. Спасибо, - person user2100039; 18.03.2013
comment
есть проблема после [0-9]/{j=0; - незавершенное регулярное выражение для { перед j. Идеи? - person user2100039; 18.03.2013

Предполагая, что каждое местоположение имеет одинаковое количество строк данных:

numcols=$(tac input_file | awk '$1 == "Location" {print $2; exit}')
pr -t -s --columns=$numcols input_file

Поскольку вы знаете, сколько строк в каждом местоположении, рассчитайте количество местоположений с помощью:

numcols=$(( $(wc -l < input_file) / 277 ))
person glenn jackman    schedule 18.03.2013
comment
спасибо - в заголовках Location в реальном файле не используется слово Location, а скорее это уникальные местоположения, такие как Flatiron, Wolfbog, Mesavista и т. д. Строки данных = 276 + заголовок для каждого фрагмента данных, который необходимо распечатать как новый столбец. Спасибо! - person user2100039; 18.03.2013
comment
glenn: я получаю ошибку неправильного имени переменной, когда запускаю этот код, и такое же сообщение об ошибке при отдельном запуске кода numcols, чтобы найти количество местоположений. Идеи? - person user2100039; 19.03.2013
comment
Действительно? какую оболочку вы используете (bash/csh/...)? Покажите нам код, который вы на самом деле выполнили. Обратите внимание, что внешние скобки двойные, а внутренние скобки одинарные. - person glenn jackman; 19.03.2013