Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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

share|improve this question
2  
tr is entirely character based: you asked tr to remove newlines and all 'G', 'r', 'o', 'u', and 'p'. –  glenn jackman Mar 30 '12 at 1:01
    
aha, I thought it was a regex, thanks –  carillonator Mar 30 '12 at 2:46

7 Answers 7

up vote 37 down vote accepted

can't test right now, but

... | paste - - 

should do it

share|improve this answer
1  
+1 - works and is elegant. (It puts a tab between the lines - paste -d ' ' - - will add a space instead if required) –  cyberx86 Mar 30 '12 at 1:20
2  
Could you please explain how does the command work? Why are there two -? Thanks –  bbaja42 Mar 30 '12 at 8:55
4  
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 2 "-" arguments, then paste takes 2 lines from stdin. And so on. See the man page. –  glenn jackman Mar 30 '12 at 10:33

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:

share|improve this answer

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}'
share|improve this answer
1  
A late comment: 1) always use a format specifier for printf in case the string has percent signs, 2) to avoid the duplicated last line, set $0 to "" -- awk '{printf "%s", $0; $0=""; getline; print " " $0}' –  glenn jackman Dec 10 '12 at 21:47

How about using grep ?

.. | grep -v '^Group State'
share|improve this answer
    
That eliminates the alternate lines. The OP wants them appended. –  Dennis Williamson Mar 30 '12 at 6:51
    
Yeah, after re-reading the question I just realized that :) –  pkhamre Mar 30 '12 at 6:52

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.

share|improve this answer

In bash:

... | while read l1; do read l2; echo "$l1 $l2"; done
share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.