7

This question already has an answer here:

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?

marked as duplicate by αғsнιη, Stephen Rauch, G-Man, Jeff Schaller, sebasth Oct 31 '17 at 20:37

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.

  • 4
    try echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE" | cat - file1 > file2 – Sundeep Oct 31 '17 at 16:07
  • ... or (echo ....; cat file1) > file2. – NickD Oct 31 '17 at 16:25
11

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
  • This is exactly what I would have said if you hadn’t beaten me to it! – G-Man Oct 31 '17 at 17:53
8

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

sed  -i '1i FID IID PAT MAT SEX PHENOTYPE' test.txt
2

Use the append operator instead >> :

echo -e "FID\tIID\tPAT\tMAT\tSEX\tPHENOTYPE" > file2 && cat file1 >> file2
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).

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
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

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