16

I have data:

7456 7456 0 0 0 2
7463 7463 0 0 1 2

I want to add column headers so the output is:

FID IID PAT MAT SEX PHENOTYPE 
7456 7456 0 0 0 2
7463 7463 0 0 1 2

I have tried echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE" | cat file1 > file2

But this is copying the original file and not the headers.

sed '1i\FID, IID, PAT, MAT, SEX PHENOTYPE' file1 > file2

has the error

sed: 1: "1i\FID, IID, PAT, MAT,  ...": extra characters after \ at the end of i command

Any advice please?

Satō Katsura
  • 13,138
  • 2
  • 31
  • 48
A.M16
  • 221
  • 1
  • 3
  • 6

6 Answers6

19

Your try with

echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE" | cat file1 > file2

is nearly functional, but cat won't do anything with its standard input (containing the actual headers). The following will work:

echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE" | cat - file1 > file2

cat will interpret - as standard input, and will insert the output of echo before adding on the contents of file1.

An alternative:

{ echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE"; cat file1; } >file2

or

( echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE"; cat file1 ) >file2
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
17

This GNU sed adds the text as the first line in the file:

sed  -i '1i FID IID PAT MAT SEX PHENOTYPE' test.txt
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Jaroslav Kucera
  • 9,422
  • 5
  • 15
  • 28
3

Use the append operator instead >> :

echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE" > file2 && cat file1 >> file2
Joe Healey
  • 664
  • 1
  • 6
  • 18
2

This error

sed: 1: "1i\FID, IID, PAT, MAT, ...": extra characters after \ at the end of i command

occurs because you are on OSX (I think), and you should have a newline after \ as POSIX specification and GNU sed allows that. like

sed '1i\
my headers' infile

Or alternatively use:

sed -e '1i\'$'\n''my headers' infile

Also if you need in-place you should have -i '' instead of only -i (on OSX or FreeBSD).

αғsнιη
  • 40,939
  • 15
  • 71
  • 114
1

Let's assume your data is space delimited as you've shown. The following will do the formatting and get what you want.

awk -vOFS="\t" '$1=$1; BEGIN { str="FID IID PAT MAT SEX PHENOTYPE"; split(str,arr," "); for(i in arr) printf("%s\t", arr[i]);print}' infile
Valentin Bajrami
  • 9,244
  • 3
  • 25
  • 38
1

As an alternative to the ugly

echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE"

you could use

head=( FID IID PAT MAT SEX PHENOTYPE )
( IFS=$'\t'; echo "${head[*]}"; cat file ) > file2

which localizes changes to the global IFS variable into a subshell

glenn jackman
  • 84,176
  • 15
  • 116
  • 168