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

39

команда 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" " "но он удалил все новые строки и съел некоторые другие письма. Благодарность

carillonator
источник
2
trполностью на основе символов: вы попросили tr удалить символы новой строки и все 'G', 'r', 'o', 'u' и 'p'.
Гленн Джекман

Ответы:

80

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

... | paste - - 

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

Гленн Джекман
источник
5
+1 - работает и элегантно. (Он помещает вкладку между строками - paste -d ' ' - -вместо этого добавит пробел, если требуется)
cyberx86
4
Не могли бы вы объяснить, как работает команда? Почему их два -? Спасибо
bbaja42
7
pasteиспользуются для конкатенации соответствующих строк из файлов: paste file1 file2 file3 .... Если один из аргументов «file» - «-», то строки читаются из стандартного ввода. Если есть 2 аргумента "-", тогда вставка занимает 2 строки из стандартного ввода. И так далее. Смотрите справочную страницу .
Гленн Джекман
10

Одна возможность:

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

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

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

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

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

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

cyberx86
источник
8

Если вы хотите использовать 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}'
Приостановлено до дальнейшего уведомления.
источник
1
Поздний комментарий: 1) всегда используйте спецификатор формата для printf в случае, если строка имеет знаки процента, 2) чтобы избежать дублирования последней строки, установите $ 0 в "" -awk '{printf "%s", $0; $0=""; getline; print " " $0}'
glenn jackman
3

Наиболее идиоматический способ сделать это 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новая строка.

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

Больше информации в Idiomatic awk .

fedorqui
источник
2

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

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

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

Брет Макмиллан
источник
Это удаляет каждую новую строку, а не любую другую новую строку.
Трентон
2

В Баш:

... | while read l1; do read l2; echo "$l1 $l2"; done
jfg956
источник
1

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

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

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

Крис Кокнат
источник
-1

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

.. | grep -v '^Group State'
pkhamre
источник
Это устраняет альтернативные линии. ОП хочет, чтобы они были добавлены.
Приостановлено до дальнейшего уведомления.
Да, после перечитывания вопроса я только что понял это :)
pkhamre