54

a bash commands outputs this:

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

I'd like to pipe it to something to make it look like this:

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
[...]

i.e. remove every other newline

I tried ... |tr "\nGroup" " " but it removed all newlines and ate up some other letters as well. thanks

8 Answers8

104

TL;DR:

This should do it:

    ... | paste - - 

Details

paste is used to concatenate corresponding lines from files:

paste file1 file2 file3 .... 

If one of the "file" arguments is -, then lines are read from standard input.

If there are two - arguments, then paste takes 2 lines from stdin. And so on.

See the man page.

Potherca
  • 105
11

One possibility is:

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

If the line number is evenly divisible by 2, end with a new line, otherwise, end with a space.

(Tested on: CentOS 6, GNU Awk 3.1.7)

Using sed (see explanation):

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

Further reading:

cyberx86
  • 21,105
8

If you want to use sed, there's no reason to read the whole file into memory. You can merge every other line like this:

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

Use any character you'd like instead of the space.

Here's another way using awk:

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

The if/else handles the case where there is an odd number of lines in the file. Without it, the odd last line gets printed twice. Otherwise, for comparison, you could do:

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

The most idiomatic way to do it in awk is as follows:

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

It outputs:

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

To explain it we need to define each one of the built-in variables:

  • RS record separator. Defaults to \n (new line).
  • ORS output record separator. Defaults to \n (new line).
  • FS field separator. Defaults to (space).
  • NR number of record.

As the default record separator is the new line, a record is, as default, a line.

NR%2 is the modulus of NR/2, so that it will be either 0 or 1. 0 for even lines and 1 for odd lines.

var=condition?condition_if_true:condition_if_false is the ternary operator.

All together, saying ORS=NR%2?FS:RS we are defining the output record separator:

  • if the number of record is on the form 2k + 1, that is, on even lines, then the output record separators is set to FS, that is, a space.
  • if the number of record is on the form 2k, that is, on odd lines, then the output record separators is set to RS, that is, a new line.

This way, odd lines end with a space, that is then joined with the next line. After that line, a new line is printed.

More info in Idiomatic awk.

fedorqui
  • 278
3

This works for me on Linux:

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

This replaces an empty space for a newline character; you must escape the newline character for things to work correctly.

2

In bash:

... | while read l1; do read l2; echo "$l1 $l2"; done
jfg956
  • 1,136
1

If Perl is an option:

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

s/\n/ / replaces newline with space
$. is the line number

Chris Koknat
  • 111
  • 3
-2

How about using grep ?

.. | grep -v '^Group State'
pkhamre
  • 6,400