0

This question already has an answer here:

I have four files;

file1:

gene_id FPKM
TRINITY_DN56960_c4_g1 36.91
TRINITY_DN42427_c0_g1 12.83
TRINITY_DN48728_c0_g1 6.22
TRINITY_DN50706_c0_g2 6604.75
TRINITY_DN51449_c1_g1 8.19
TRINITY_DN48996_c1_g1 28.21

file2:

gene_id FPKM
TRINITY_DN48728_c0_g1 6.05
TRINITY_DN50706_c0_g2 5176.34
TRINITY_DN51449_c1_g1 7.58
TRINITY_DN48996_c1_g1 16.47
TRINITY_DN42427_c0_g1 14.03
TRINITY_DN56960_c4_g1 80.91 

file 3:

gene_id FPKM
TRINITY_DN56960_c4_g1 90.91
TRINITY_DN42427_c0_g1 24.03
TRINITY_DN51449_c1_g1 6.58
TRINITY_DN48996_c1_g1 26.47
TRINITY_DN48728_c0_g1 7.05
TRINITY_DN50706_c0_g2 4176.34

file 4:

gene_id FPKM
TRINITY_DN50706_c0_g2 9176.34
TRINITY_DN56960_c4_g1 120.91
TRINITY_DN42427_c0_g1 34.03
TRINITY_DN48728_c0_g1 7.05
TRINITY_DN51449_c1_g1 7.58
TRINITY_DN48996_c1_g1 36.5

I want the output file like this:

gene_id               FPKM1 FPKM2 FPKM3 FPKM4
TRINITY_DN42427_c0_g1 12.83 14.03 24.03 34.03
TRINITY_DN48728_c0_g1 6.22 6.05 7.05 7.05
TRINITY_DN48996_c1_g1 28.21 16.47 26.47 36.5
TRINITY_DN50706_c0_g2 6604.75 5176.34 4176.34 9176.34
TRINITY_DN51449_c1_g1 8.19 7.58 6.58 7.58
TRINITY_DN56960_c4_g1 36.91 80.91 90.91 120.91

So how can I do this in a shell script?

marked as duplicate by don_crissti, roaima, Jeff Schaller, dr01, Archemar May 27 '16 at 11:38

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Either solution there will work, you only need minor adjustments e.g. { printf '%s %s %s %s %s\n' gene_id FPKM1 FPKM2 FPKM3 FPKM4; paste <({ head -n 1 >/dev/null; sort; } <file1) <({ head -n 1 >/dev/null; sort; } <file2 | cut -f2) \ <({ head -n 1 >/dev/null; sort; } <file3 | cut -f2) <({ head -n 1 >/dev/null; sort; } <file4 | cut -f2); } | column -t This assumes your files are tab-delimited. – don_crissti May 27 '16 at 10:42
  • i have problem with this solution, i run it but there is still an error: paste: /proc/self/fd/15: No such file or directory gene_id FPKM1 FPKM2 FPKM3 FPKM4 – Mehdi May 27 '16 at 10:59
  • @Mehdi Remove \ from don_crissti solution. – jimmij May 27 '16 at 11:04
  • i removed \ but there is still a problem, i have two columns instead of five ones. one column for gene_id and the second is FPKM of one of 4 files. the headers are correct. – Mehdi May 27 '16 at 11:39
  • @Mehdi - if your columns are space delimited then you have to use cut -d' ' -f2 that is specify that space is a delimiter. Either that or edit your files before processing them and replace all spaces with tabs. – don_crissti May 27 '16 at 13:14
1

This uses sponge from Debian's moreutils package. No bashisms.

Backup the four input files however you like, (since this will change them), then:

# enumerate headers of each file, then sort each file, in place
for f in file* ; do
    sed '1s/.*/&'"$f"'/;s/file//' $f | sort | sponge $f
done
# join sorted files, output to 'fileN'
for f in 34 N2 N1 ; do join --header file[$f] | sponge fileN ; done
# reformat header, in place
sed -i '1s/d/d              /' fileN
cat fileN

Output:

gene_id               FPKM1 FPKM2 FPKM3 FPKM4
TRINITY_DN42427_c0_g1 12.83 14.03 24.03 34.03
TRINITY_DN48728_c0_g1 6.22 6.05 7.05 7.05
TRINITY_DN48996_c1_g1 28.21 16.47 26.47 36.5
TRINITY_DN50706_c0_g2 6604.75 5176.34 4176.34 9176.34
TRINITY_DN51449_c1_g1 8.19 7.58 6.58 7.58
TRINITY_DN56960_c4_g1 36.91 80.91 90.91 120.91

Not the answer you're looking for? Browse other questions tagged or ask your own question.