Транспонируйте короткие столбцы в строку и переставьте позиции с помощью awk/sed

У меня есть текущий набор данных, как показано ниже:

11 48 5300 8000 1 0
ht2 
ht2 
11 49 5300 8000 1 0
ht2 
ht2 
11 50 5300 8000 2 0
ht2 
ht2 
11 51 5300 8000 2 0
ht2 
ht3 
11 52 5300 8000 2 0
ht2 
ht3

Я хотел бы изменить порядок данных следующим образом:

11 48 5300 8000 1 0 ht2 ht2
11 49 5300 8000 1 0 ht2 ht2
11 50 5300 8000 2 0 ht2 ht2
11 51 5300 8000 2 0 ht2 ht3
11 52 5300 8000 2 0 ht2 ht3

Буду очень признателен за любую помощь/предложения от вас. Заранее спасибо.


person user3874325    schedule 24.07.2014    source источник
comment
всегда лучше попробовать что-то самостоятельно и опубликовать свои усилия в своем вопросе.   -  person macfij    schedule 25.07.2014
comment
Так что извините, что я столкнулся с некоторыми ошибками в форматировании данных, когда пытался их редактировать.   -  person user3874325    schedule 25.07.2014


Ответы (4)


Вы хотите прочитать три входные строки и записать их как одну строку. Awk имеет функцию getline, которая упрощает эту задачу:

$ awk '{a=$0; getline; b=$0; getline; print a, b, $0}' dataset 
11 48 5300 8000 1 0 ht2 ht2 
11 49 5300 8000 1 0 ht2 ht2 
11 50 5300 8000 2 0 ht2 ht2 
11 51 5300 8000 2 0 ht2 ht3 
11 52 5300 8000 2 0 ht2 ht3 

Принимая каждую команду awk по очереди:

  • a=$0;

    Сохраните значение первой строки в переменной a.

  • получить линию;

    Читать во второй строке.

  • b=$0;

    Сохраните значение второй строки в переменной b.

  • получить линию;

    Читать в третьей строке.

  • напечатать а, б, $0

    Распечатайте все три строки.

person John1024    schedule 24.07.2014
comment
Вам следует избегать использования getline. Выполните поиск и прочитайте сообщение Ed awk.freeshell.org/AllAboutGetline. - person Jotne; 25.07.2014
comment
@Jotne Спасибо за эту ссылку. Я читаю это. Если я напишу код, использующий нетривиальные возможности getline, я обязательно на него обращусь. - person John1024; 25.07.2014
comment
@Jotne, хотя есть предостережения относительно использования getline в подобных случаях, я не понимаю, почему люди предлагают против этого? - person ; 25.07.2014

Вот awk

awk 'NR%3==1 {f=$0} NR%3==2 {g=$0} NR%3==0 {print f,g $0}' file
11 48 5300 8000 1 0 ht2 ht2
11 49 5300 8000 1 0 ht2 ht2
11 50 5300 8000 2 0 ht2 ht2
11 51 5300 8000 2 0 ht2 ht3
11 52 5300 8000 2 0 ht2 ht3
person Jotne    schedule 24.07.2014
comment
Большое спасибо за код. Это работает для небольшого набора подданных выше. Однако я не мог понять, почему это не работает для ниже 1 10000 0 0 1 0 ht2 ht2 1 8400 0 0 2 0 ht2 ht2 1 61 10000 8400 1 0 ht2 ht2 1 62 10000 8400 2 0 ht2 ht2 1 63 10000 8400 1 0 ht2 ht2 1 80 10000 8400 2 0 ht2 ht2 1 81 10000 8400 2 0 ht2 ht2 1 82 10000 8400 1 0 ht2 ht2 1 83 10000 8400 1 0 ht2 ht2 - person user3874325; 25.07.2014
comment
@user3874325 user3874325 Разместите эти данные в своем исходном сообщении, так как форматирование здесь не работает. - person Jotne; 25.07.2014
comment
@user3874325 user3874325 Проблема в том, что вывод выглядит как ht2ht2 вместо ht2 ht2? Если это так, проблема заключается в том, что исходные данные в вопросе имели завершающие пробелы после строк ht, которые сохраняет awk и которые сделали вывод print f,g $0 правильным. Если в ваших новых данных нет этого пробела, используйте вместо него print f,g,$0. - person John1024; 25.07.2014

paste -d" " - - - < file приведет к следующему результату:

11 48 5300 8000 1 0 ht2  ht2
11 49 5300 8000 1 0 ht2  ht2 
11 50 5300 8000 2 0 ht2  ht2 
11 51 5300 8000 2 0 ht2  ht3 
11 52 5300 8000 2 0 ht2  ht3
person Florin Stingaciu    schedule 24.07.2014
comment
@Jotne Исправлено. Спасибо что подметил это. Разделитель по умолчанию для вставки — tab. - person Florin Stingaciu; 25.07.2014
comment
У вас еще есть одно свободное место. 11 48 5300 8000 1 0 ht2 ht2 Не уверен, почему ваш вывод не показывает это. - person Jotne; 25.07.2014
comment
@Jotne Мой результат действительно совпадает с вашим. Я вижу это дополнительное пространство. Если я удалю пробел после каждого ht2 в каждой строке, я получу правильный вывод. - person Florin Stingaciu; 25.07.2014
comment
Если вы посмотрите на мой вывод, я должен использовать f,g $0, а не f,g,$0, чтобы не допустить лишнего места для печати. Это мелочь, так что оставьте это, и пусть ОП это исправит :) - person Jotne; 25.07.2014
comment
Спасибо за предложение. Однако я не мог понять, что вы имели в виду. Не могли бы вы дать мне более подробную информацию о пасте - - - - person user3874325; 25.07.2014
comment
Я мог получить некоторое представление о пасте. Большое спасибо за помощь. - person user3874325; 25.07.2014

sed "N;N;s/\n/ /g" YourFile

загрузить 2 строки после текущей, заменить новую строку пробелом. Пока структура не будет похожа на ваш образец, она будет работать.

person NeronLeVelu    schedule 25.07.2014