Назад | Перейти на главную страницу

bash / sed / awk / etc удалить все остальные символы новой строки

команды bash выводят это:

Runtime Name: vmhba2:C0:T3:L14
Group State: active
Runtime Name: vmhba3:C0:T0:L14
Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14
Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14
Group State: active
Runtime Name: vmhba2:C0:T2:L14
Group State: active

Я бы хотел передать его по конвейеру, чтобы он выглядел так:

Runtime Name: vmhba2:C0:T1:L14 Group State: active 
Runtime Name: vmhba3:C0:T3:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T2:L14 Group State: active
[...]

т.е. удалить все остальные символы новой строки

Я попытался ... |tr "\nGroup" " " но он удалил все символы новой строки и съел некоторые другие буквы. Спасибо

не могу проверить прямо сейчас, но

... | paste - - 

должен сделать это

Одна из возможностей:

awk 'ORS=NR%2?" ":"\n"'

Если номер строки делится на 2 без остатка, в конце ставьте новую строку, в противном случае - пробелом.

(Проверено на: CentOS 6, GNU Awk 3.1.7)

Используя sed (см. объяснение):

sed ':a;N;$!ba;s/\nGroup/ Group/g'

Дальнейшее чтение:

Если вы хотите использовать sed, нет смысла читать весь файл в память. Вы можете объединить все остальные строки следующим образом:

sed 'N;s/\n/ /' inputfile

Используйте любой символ вместо пробела.

Вот еще один способ использования awk:

awk '{printf "%s", $0; if (getline) print " " $0; else printf "\n"}' inputfile

В if/else обрабатывает случай, когда в файле есть нечетное количество строк. Без него последняя нечетная строка печатается дважды. В противном случае для сравнения можно было бы сделать:

awk '{printf "%s", $0; getline; print " " $0}'

Это работает для меня в Linux:

... | tr "\\n" " "

Это заменяет пустое место для символа новой строки; ты должен экранируйте символ новой строки, чтобы все работало правильно.

Самый идиоматичный способ сделать это в awk как следует:

awk 'ORS=NR%2?FS:RS' file

Он выводит:

Runtime Name: vmhba2:C0:T3:L14 Group State: active
Runtime Name: vmhba3:C0:T0:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14 Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14 Group State: active
Runtime Name: vmhba2:C0:T2:L14 Group State: active

Чтобы объяснить это, нам нужно определить каждую из встроенных переменных:

  • RS разделитель записей. По умолчанию \n (новая линия).
  • ORS разделитель выходной записи. По умолчанию \n (новая линия).
  • FS разделитель полей. По умолчанию (пространство).
  • NR номер записи.

Поскольку разделителем записей по умолчанию является новая строка, записью по умолчанию является строка.

NR%2 это модуль NR/2, так что будет либо 0 или 1. 0 для четных линий и 1 для нечетных строк.

var=condition?condition_if_true:condition_if_false - тернарный оператор.

Все вместе, говоря ORS=NR%2?FS:RS мы определяем разделитель выходной записи:

  • если номер записи есть в форме 2k + 1, то есть в четных строках, то разделители выходных записей устанавливаются на FS, то есть пробел.
  • если номер записи есть в форме 2k, то есть на нечетных строках, то разделители выходных записей устанавливаются на RS, то есть новую строку.

Таким образом, нечетные строки заканчиваются пробелом, который затем соединяется со следующей строкой. После этой строки печатается новая строка.

Больше информации в Идиоматический awk.

В bash:

... | while read l1; do read l2; echo "$l1 $l2"; done

Если Perl - вариант:

perl -pe 's/\n/ / if $. % 2 == 1' file

s/\n/ / заменяет новую строку пробелом
$. это номер строки

Как насчет использования grep ?

.. | grep -v '^Group State'