M BUZZ CRAZE NEWS
// news

How can I merge files on a line by line basis?

By Daniel Rodriguez

cat file1

foo
ice
two

cat file2

bar
cream
hundred

Desired output:

foobar
icecream
twohundred

file1 and file2 will always have the same amount of lines in my scenario, in case that makes things easier.

5 Answers

The right tool for this job is probably paste

paste -d '' file1 file2

See man paste for details.


You could also use the pr command:

pr -TmJS"" file1 file2

where

  • -T turns off pagination
  • -mJ merge files, Joining full lines
  • -S"" separate the columns with an empty string

If you really wanted to do it using pure bash shell (not recommended), then this is what I'd suggest:

while IFS= read -u3 -r a && IFS= read -u4 -r b; do printf '%s%s\n' "$a" "$b"
done 3<file1 4<file2

(Only including this because the subject came up in comments to another proposed pure-bash solution.)

2

Through way:

awk '{getline x<"file2"; print $0x}' file1
  • getline x<"file2" reads the entire line from file2 and holds into x variable.
  • print $0x prints the whole line from file1 by using $0 then x which is the saved line of file2.
1

paste is the way to go. If you want to check some other methods, here is a python solution:

#!/usr/bin/env python2
import itertools
with open('/path/to/file1') as f1, open('/path/to/file2') as f2: lines = itertools.izip_longest(f1, f2) for a, b in lines: if a and b: print a.rstrip() + b.rstrip() else: if a: print a.rstrip() else: print b.rstrip()

If you have few number of lines:

#!/usr/bin/env python2
with open('/path/to/file1') as f1, open('/path/to/file2') as f2: print '\n'.join((a.rstrip() + b.rstrip() for a, b in zip(f1, f2)))

Note that for unequal number of lines, this one will end at the last line of the file that ends first.

Also, with pure bash (notice that this will totally ignore empty lines):

#!/bin/bash
IFS=$'\n' GLOBIGNORE='*'
f1=($(< file1))
f2=($(< file2))
i=0
while [ "${f1[${i}]}" ] && [ "${f2[${i}]}" ]
do echo "${f1[${i}]}${f2[${i}]}" >> out ((i++))
done
while [ "${f1[${i}]}" ]
do echo "${f1[${i}]}" >> out ((i++))
done
while [ "${f2[${i}]}" ]
do echo "${f2[${i}]}" >> out ((i++))
done
4

The perl way, easy to understand:

#!/usr/bin/perl
$filename1=$ARGV[0];
$filename2=$ARGV[1];
open(my $fh1, "<", $filename1) or die "cannot open < $filename1: $!";
open(my $fh2, "<", $filename2) or die "cannot open < $filename2: $!";
my @array1;
my @array2;
while (my $line = <$fh1>) { chomp $line; push @array1, $line;
}
while (my $line = <$fh2>) { chomp $line; push @array2, $line;
}
for my $i (0 .. $#array1) { print @array1[$i].@array2[$i]."\n";
}

Start with:

./merge file1 file2

Output:

foobar
icecream
twohundred

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy