Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How to write a shell script which uses awk to read in the data file students.txt and output the data in the tabbed format as shown:

Surname Forename MSc Stream Date of Birth
Smith John IT 15.01.1986
Taylor Susan IT 04.05.1987
Thomas Steve MIT 19.04.1986
  • Do not worry if tabbed columns don’t line up.

  • The distance between each of (Surname, Forename, MSc Stream and Date of Birth) column is one tab.

Question:

Why this code bellow doesn't work for me?

awk 'BEGIN {IFS=" "} {OFS="\t"} {print $1,$2,$3,$4}' students.txt
share|improve this question
2  
What do you mean "doesn't work"? Also, '{IFS=" "}' executed only before actual processing, while '{OFS="\t"}' executed after reading each row. And I don't see variable IFS in awk man page, did you mean FS? If so, it's already set to separate fields on whitespace, not just single space. –  gelraen Apr 4 '11 at 20:23
2  
Please learn to use the formatting possibilities. You can see what I did to make your question more readable. Use the icons above the question box; click the ? icon to see the available markup options. –  Gilles Apr 4 '11 at 20:25
    
@gelraen: Yup, you got it. –  Gilles Apr 4 '11 at 20:25
    
What about the header? How can you awk that?... I've barely touched on awk, so I'm guessing that would be a custom process for the first line in the main section... (but I've go no idea how) –  Peter.O Apr 5 '11 at 9:18

2 Answers 2

awk '{$1=$1}1' OFS="\t" students.txt

Proof of Concept

$ awk '{$1=$1}1' OFS="\t" students.txt
Surname Forename        MSc     Stream  Date    of      Birth
Smith   John    IT      15.01.1986
Taylor  Susan   IT      04.05.1987
Thomas  Steve   MIT     19.04.1986

Explanation

The reason it didn't work is because awk requires one of the fields to be changed before it applies the new output field separator. The workaround for this defect (IMHO) is to just set a field to itself, hence the $1=$1


For this simple type of change, you're better off using tr or sed

tr ' ' '\t' < students.txt
sed 's/ /\t/g' students.txt
share|improve this answer
2  
Code from question works too (at least on GNU and FreeBSD implementations). "Defect" you described may take place because print prints $0 and $0 does not get rebuilt with new OFS when nothing was changed. Not sure is such behaviour a bug or it really should work this way. But print $1,$2,$3,$4 still uses OFS to separate fields. –  gelraen Apr 4 '11 at 22:16
    
@galrean: you're right, this 'defect' is limited to print $0 and its variations. –  SiegeX Apr 4 '11 at 22:51
    
+1 for offering simple tr and sed options. –  glenn jackman Apr 5 '11 at 14:25
    
your code worked great in sed, < sed 's/ /\t/g' students.txt >. But the one in AWK didn't.! –  Host Post Apr 23 '11 at 9:31

This is wrong:

awk 'BEGIN {IFS=" "} {OFS="\t"} {print $1,$2,$3,$4}' students.txt

because you're setting OFS too late (not in the BEGIN block). Do this:

awk 'BEGIN {OFS="\t"} {print $1,$2,$3,$4}' students.txt

Don't forget to change your header to have 4 space-separated fields:

Surname Forename MSc_Stream Date_of_Birth
share|improve this answer
    
I got this message (Syntax error at source line 1).. –  Host Post Apr 6 '11 at 9:17
    
@Host, did you cut and paste that code exactly? I do not get any syntax errors using any of the awk implementations at my disposal. –  glenn jackman Apr 6 '11 at 13:08
    
@asoundmove, I am sorry that I couldn't be active.. this was because of some unexpected condition! Thanks –  Host Post Apr 23 '11 at 9:13
    
@asoundmove: OP doesn't have enough reputation to upvote. –  Mikel Apr 26 '11 at 0:29
1  
@Mikel, Ok, I did not remember the early restrictions. How about accepting an answer? –  asoundmove Apr 26 '11 at 2:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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