2

I want to get the first word in every line from a file. Unfortunately a lot of lines begin with space(s). So I try to get the firs word with the following:

awk -F'[ \t]+' '{print $1}' < MyFile.txt, but it's not working. I try this echo " some string: here" | awk -F'[ \t]+' '{print $1}' and the results is blank line (I thing that it prints empty string). So why this is not working? I want to make it works with the awk command and explicitly passed delimiter (with educational purposes)

Thanks in advance.

  • 9
    you'd be better off without specifying delimiter I think, let awk do its automatic field detection on white-spaces... echo " some string: here" | awk '{print $1}' – Sundeep Jan 10 '17 at 14:27
  • 1
    Please post a sample from your input file – Eng7 Jan 10 '17 at 16:22
0

awk ignores leading blank spaces when assigning fields and the default command is print. So this should work fine:

awk '{print $1}'
  • I think this misses the point of what "why" really means. You're giving implementation details rather than either purpose, or documented behavior. The POSIX specifications for Awk would be a better reference to answer the question "why." – Wildcard Jan 10 '17 at 23:43
  • @Wildcard feedback noted. Post edited to remove extraneous content. – Dan Jan 10 '17 at 23:47
  • Don't get me wrong; it's sometimes good to dig into the source code. But it more answers the how than the why. – Wildcard Jan 11 '17 at 0:02
  • @Wildcard that makes sense. The why is probably simply "the RegEx delimiter (-F) isn't doing what was intended because of the way the separator array is handled in awk. In this case, the default behavior is best and accomplishes the intended goal of extracting the first column". – Dan Jan 11 '17 at 0:33
0

You are specifying a field separator for Awk that is made up of at least a space or a tab character.

You feed the string " some string: here" into Awk and ask it to print the first field.

You get no output because the first field is empty.

The fields in this string are

<1:>   <2:some> <3:string:> <4:here>

$ echo '   some string: here' | gawk 'BEGIN {OFS="|";FS="[ \t]+"}{print $1,$2,$3,$4}'
|some|string:|here

It is more visible with comma-separated input data, like

,some,string:,here

Note also that using a regular expression for FS is an extension to Awk, implemented in GNU Awk and Mawk.

0

In awk, the default field separator -F " " or BEGIN{FS=" "} follows a special convention

  • (1) initial spaces and final spaces are ignored
  • (2) splits by [ \t]+

Point (1) -- ignoring initial/final spaces -- just apply when field separator is exactly " ".

This behaviour is in fact what we would expect.

The default awk '{print $1}' works find and so does awk -F' ' '{print $1}'.


There is another similar convention for the input record separator(RS): when RS="" it stands for paragraph separation:

  • (1) separator is one or more empty lines
  • (2) initial and final empty lines are ignored.

Point (2) -- ignoring initial/final empty lines -- just apply when input record separator is exactly "".

  • 4
    Note that depending on the awk implementation, with FS=" " (the default), it will split either on [ \t]+ or [[:blank:]]+. – Stéphane Chazelas Jan 10 '17 at 17:08
  • @JJao, thank you, but why my code does not working? And why is your code working? I thought that this should return first field (this between first two whitespaces - empty string). Thanks in advance. – DPM Jan 10 '17 at 18:47
  • @DPM , according to AWK manual, this "special convention", namely point (1) just is activated when FS is exactly ' ' – JJoao Jan 11 '17 at 8:09
  • 1
    Rather than "register separator", RS is the "input record separator". – Kusalananda Jan 11 '17 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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