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.

I'm trying to split a line that I have no control over the format of. If parameter 7 and 8 are missing which is possible they will be replaced by a space so I would end up with,

field1 field2 field3 field4 field5 field6   field9

At the moment in this situation field 9 is being read as field 7. Much searching has led me to believe that the following should work but it isn't doing. It's probably some minor syntax error on my part but I can't seem to spot it.

word1=`echo $LINE | awk 'BEGIN { FS="[ ]" } ; { print $9 }'`
share|improve this question
add comment

3 Answers

The LINE parameter isn't quoted so wordsplitting happens upon the expansion of $LINE in echo $LINE and by the time awk receives any input, you have 7 words(as seen by the shell) all separated by a single space. You want echo to output it as one word(again, as seen by the shell) so the whitespace in your line isn't mangled before awk can process it. That is what quoting the parameter prevents.

# How you want it to be given to awk:
$ printf '<%s> ' "$LINE"; echo
<field1 field2 field3 field4 field5 field6   field9> 
# Your attempt:
$ printf '<%s> ' $LINE; echo
<field1> <field2> <field3> <field4> <field5> <field6> <field9> 

Notice how the extra whitespace is gone between field6 and 9.

You should always quote expansions, you will more likely break something by not quoting expansions than by quoting them.

share|improve this answer
    
Thanks. One day I'll understand awk. Probably about the same time they replace it with something better. –  dazedandconfused Nov 1 '13 at 15:05
    
@dazedandconfused, the problem is not with awk but with you not quoting $LINE passed to echo (and using echo btw) –  Stephane Chazelas Nov 1 '13 at 15:21
    
@dazedandconfused I went into a little more detail with my answer. –  llua Nov 1 '13 at 15:54
add comment

A very useful parameter in awk when dealing with variable input length is the NF one, the number of fields.

lastword=`echo $LINE | awk '{ print $NF }'`

That will always print the last column, irrespective of the missing ones. If some fields in the middle are missing, counting back from the last field works pretty well too.

A sample file where missing/empty columns filled with spaces like in your example:

line1 field1 field2 field3 field4 field5 field6 field7 field8 field9
line2 field1 field2 field3 field4 field5 field6  field8 field9
line3 field1 field2 field3 field4 field5   field8 field9

and

awk '{print $1 " " $2 " " $(NF-1) " " $NF}' file

    line1 field1 field8 field9
    line2 field1 field8 field9
    line3 field1 field8 field9
share|improve this answer
add comment

To do it in ksh93:

set -f
IFS='  ' # two spaces
set -- $LINE
printf '%s\n' "$9"

Doubling the space removes the special behaviour by which sequences of spaces are considered as one and leading and trailing spaces are ignored like in zsh.

share|improve this answer
    
+1. I see this working with ksh but not bash; Is IFS splitting done differently in bash? –  1_CR Nov 1 '13 at 17:24
1  
Yes, that feature is only in zsh and ksh93 –  Stephane Chazelas Nov 1 '13 at 17:45
add comment

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.