Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

At the Linux/Unix command line, I want to turn this:

A
B
C
A
B
C
.
.
.

into this:

A,B,C
A,B,C
...

Is there a simple built-in command to do this, or does this require diving into Awk, Perl, etc.?

share|improve this question
up vote 7 down vote accepted

Don't know such built-in. Using Bash you can:

while read a && read b && read c ; do echo $a,$b,$c ; done < file
share|improve this answer
    
If you have only 5 lines, you may not want to lose lines 4 and 5 just because you don't have line 6. – musiphil Oct 16 '14 at 17:19

That is horrible, surely something like

tr \\n ' '

would do the same thing?

So for e.g. to join lines of the file *file_lines* use

cat file_lines | tr \\n ' '
share|improve this answer
4  
He didn't want all of it on a single line, it seems. – l0b0 Feb 17 '12 at 10:42
    
Exactly. Referencing the problem statement, this would produce a single line with everything on it (A B C A B C A B C A B C A B C ...) which is not what was requested. – Alan Krueger Feb 17 '12 at 17:08

If you're lucky enough to have no spaces in the input, then

xargs -n3 echo |tr ' ' ,

would do it.

share|improve this answer
    
That's a good one that I was going to suggest. Very elegant. If you do have spaces, use xargs -l3 – xpt Aug 20 '15 at 0:49
    
The tr will mangle the output if there are spaces in the input, even with xargs -l – Steven Taschuk Aug 20 '15 at 1:16
    
Alright then, I'll provide my own answer. – xpt Aug 20 '15 at 1:18

Here is a solution in python:

#!/usr/bin/python3

def njoin(filename, outfn="", n=3, linesuffix=" "):
    if not outfn:
        outfn = filename + ".join"
    with open(filename) as infh, open(outfn, "w") as outfh:
        nline = 0
        for line in infh:
            if nline % n != n-1:
                line = line.rstrip() + linesuffix
            outfh.write(line)
            nline += 1

In your case you can use the function like this:

njoin("/path/to/file", n=3, linesuffixe=",")
share|improve this answer

The sample you gave have 3 lines but your topic emphasize on N lines of input, so I would assume that 3 lines is only for illustration purpose, and what you really need is that N lines of input, which could be as much as over 10, which in turn making that accepted bash script unmanageable.

There are simple built-in commands to do this, without diving into Awk, or Perl. Here is one way.

First, the sample input,

 $ seq 12 | cat -n 
     1  1
     2  2
     3  3
     4  4
     5  5
     6  6
     7  7
     8  8
     9  9
    10  10
    11  11
    12  12

Now suppose N=4:

N=4
$ seq 12 | cat -n | sed 's/$/,/' | xargs -l$N | sed 's/,$//'
1 1, 2 2, 3 3, 4 4
5 5, 6 6, 7 7, 8 8
9 9, 10 10, 11 11, 12 12

I believe that should be close to what you are looking for.

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.