How can I merge files on a line by line basis?
cat file1
foo
ice
twocat file2
bar
cream
hundredDesired output:
foobar
icecream
twohundredfile1 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 file2See man paste for details.
You could also use the pr command:
pr -TmJS"" file1 file2where
-Tturns off pagination-mJmerge 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.)
2Through awk way:
awk '{getline x<"file2"; print $0x}' file1getline x<"file2"reads the entire line from file2 and holds into x variable.print $0xprints the whole line from file1 by using$0thenxwhich is the saved line of file2.
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 file2Output:
foobar
icecream
twohundred