How to interleave lines from two text files

UnixCommand

Unix Problem Overview


What's the easiest/quickest way to interleave the lines of two (or more) text files? Example:

File 1:

line1.1
line1.2
line1.3

File 2:

line2.1
line2.2
line2.3

Interleaved:

line1.1
line2.1
line1.2
line2.2
line1.3
line2.3

Sure it's easy to write a little Perl script that opens them both and does the task. But I was wondering if it's possible to get away with fewer code, maybe a one-liner using Unix tools?

Unix Solutions


Solution 1 - Unix

paste -d '\n' file1 file2

Solution 2 - Unix

Here's a solution using awk:

awk '{print; if(getline < "file2") print}' file1

produces this output:

line 1 from file1
line 1 from file2
line 2 from file1
line 2 from file2
...etc

Using awk can be useful if you want to add some extra formatting to the output, for example if you want to label each line based on which file it comes from:

awk '{print "1: "$0; if(getline < "file2") print "2: "$0}' file1

produces this output:

1: line 1 from file1
2: line 1 from file2
1: line 2 from file1
2: line 2 from file2
...etc

Note: this code assumes that file1 is of greater than or equal length to file2.

If file1 contains more lines than file2 and you want to output blank lines for file2 after it finishes, add an else clause to the getline test:

awk '{print; if(getline < "file2") print; else print ""}' file1

or

awk '{print "1: "$0; if(getline < "file2") print "2: "$0; else print"2: "}' file1

Solution 3 - Unix

@Sujoy's answer points in a useful direction. You can add line numbers, sort, and strip the line numbers:

(cat -n file1 ; cat -n file2 )  | sort -n  | cut -f2-

Note (of interest to me) this needs a little more work to get the ordering right if instead of static files you use the output of commands that may run slower or faster than one another. In that case you need to add/sort/remove another tag in addition to the line numbers:

(cat -n <(command1...) | sed 's/^/1\t/' ; cat -n <(command2...) | sed 's/^/2\t/' ; cat -n <(command3) | sed 's/^/3\t/' )  \
   | sort -n  | cut -f2- | sort -n | cut -f2-

Solution 4 - Unix

With GNU sed:

sed 'R file2' file1

Output:

line1.1
line2.1
line1.2
line2.2
line1.3
line2.3

Solution 5 - Unix

Here's a GUI way to do it: Paste them into two columns in a spreadsheet, copy all cells out, then use regular expressions to replace tabs with newlines.

Solution 6 - Unix

cat file1 file2 |sort -t. -k 2.1

Here its specified that the separater is "." and that we are sorting on the first character of the second field.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFrankView Question on Stackoverflow
Solution 1 - UnixcodaddictView Answer on Stackoverflow
Solution 2 - UnixsamgakView Answer on Stackoverflow
Solution 3 - UnixJoshua GoldbergView Answer on Stackoverflow
Solution 4 - UnixCyrusView Answer on Stackoverflow
Solution 5 - UnixDweditView Answer on Stackoverflow
Solution 6 - UnixSujoyView Answer on Stackoverflow