Text processing – join every two lines with commas

I have more than 1000 lines in a file. The file starts as follows (line numbers added):

Station Name
Station Code
A N DEV NAGAR
ACND
ABHAIPUR
AHA
ABOHAR
ABS
ABU ROAD
ABR

I need to convert this to a file, with comma separated entries by joining every two lines. The final data should look like

Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR
...

What I was trying was – trying to write a shell script and then echo them with comma in between. But I guess a simpler effective one-liner would do the job here may be in sed/awk.

Any ideas?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Simply use cat (if you like cats ;-)) and paste:

cat file.in | paste -d, - - > file.out

Explanation: paste reads from a number of files and pastes together the corresponding lines (line 1 from first file with line 1 from second file etc):

paste file1 file2 ...

Instead of a file name, we can use - (dash). paste takes first line from file1 (which is stdin). Then, it wants to read the first line from file2 (which is also stdin). However, since the first line of stdin was already read and processed, what now waits on the input stream is the second line of stdin, which paste happily glues to the first one. The -d option sets the delimiter to be a comma rather than a tab.

Alternatively, do

cat file.in | sed "N;s/n/,/" > file.out

P.S. Yes, one can simplify the above to

< file.in sed "N;s/n/,/" > file.out

or

< file.in paste -d, - - > file.out

which has the advantage of not using cat.

However, I did not use this idiom on purpose, for clarity reasons — it is less verbose and I like cat (CATS ARE NICE). So please do not edit.

Alternatively, if you prefer paste to cats (paste is the command to concatenate files horizontally, while cat concatenates them vertically), you may use:

paste file.in | paste -d, - -

Method 2

In case anyone landing here is looking to combine all lines into a CSV one liner, try

cat file | tr 'n' ','

Method 3

sed 'N;s/n/,/' file

Using sed, join(N) every 2 lines, and replace the newline(n) with “,”.

Method 4

For the complete set of answers, a possible awk solution may be:

awk 'NR%2==1 {printf $0","} NR%2==0 { print $0}' *file*

Method 5

paste -sd ',n' file.in > file.out

Also note that because we’re merely replacing one character with another (every other newline with a comma), we can work on the input file in place:

paste -sd ',n' file.in 1<> file.in

(but beware it might not work on non-Unix systems that have CRLF terminators (like Microsoft ones) that some emulated POSIX paste might treat in a non-Unix way)

Method 6

Here is a one-liner (though potentially millions-of-commands-run-er) using pure Bash:

(IFS=; while read -r name; do read -r code; printf '%sn" "$name,$code"; done < file.in) > file.out

I use a subshell (the paranthesis) so that I won’t have to store and restore IFS. Which one otherwise should do as to not mess up the users environment in case the source is sourced. The alternative would be to pass that new IFS only to read as in IFS= read -r name, IFS= read -r code.

The fact that all the commands in the loop are built in the shell makes its performance acceptable and is even faster than the other solutions for small files. But many people would consider it bad practice and one should be careful when generalising it to anything else.

Method 7

Hoary old chestnut of an awkidiom

awk '{ORS=NR%2?",":"n";print}' file
Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR

Method 8

Possible with perl too,

perl -pe 's/^d+.s+//;$.&1?chomp:print","' file

Method 9

For example:

seq 0 70 | xargs -L 2 | sed 's/ /,/g'

Output: ( note: xargs -L number_of_columns works nicely with most any number of columns not just every two lines)

0,1
2,3
4,5
6,7
8,9
10,11
12,13
14,15
16,17
18,19
20,21
22,23
24,25
26,27
28,29
30,31
32,33
34,35
36,37
38,39
40,41
42,43
44,45
46,47
48,49
50,51
52,53
54,55
56,57
58,59
60,61
62,63
64,65
66,67
68,69
70

Method 10

POSIX solution with pr:

pr -2 -a -t -s, file

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x