12

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?

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

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
| improve this answer | |
11

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

sed  -i '1i FID IID PAT MAT SEX PHENOTYPE' test.txt
| improve this answer | |
3

Use the append operator instead >> :

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

| improve this answer | |
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
| improve this answer | |
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

| improve this answer | |

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