0

Why do I get those strange spaces?

echo "hello world" | awk 'BEGIN{FS=""} {$1=toupper($1); printf "%s\n", $0}'

I get the same result with the simpler way.

echo "hello world" | awk 'BEGIN{FS=""} {$1=toupper($1); print}'

Output:

H e l l o   w o r l d
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
tenjohn
  • 197
  • 6
  • Not an answer to the question, but slightly related: [sed/awk capitalize strings](https://stackoverflow.com/q/11803395/8344060) – kvantour May 24 '18 at 14:13

3 Answers3

2

Setting the field separator to the empty string has special significance: it reads revery single character into a separate field. Since the output field separator, OFS, is unchanged (a blank), your assignment reshuffles the complete record and inserts OFS between every single field.

The first field/character is uppercased.

Your first and second method are equivalent because print defaults to print $0, and printf "%s\n", $0 is equivalent to print $0.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
0

FS="" means to treat each character as a separate field. $0 contains all the fields separated by OFS, the output field separator. OFS defaults to a single space, so each field is separated by a space.

If you want it to output the result without the extra space, assign to OFS

echo "hello world" | awk 'BEGIN{FS=""; OFS=""} {$1=toupper($1); printf "%s\n", $0}'
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

the reason of extra spaces is you didn't set OFS.

here is another solution

$ echo "hello world" | awk '{sub(/^./,toupper(substr($1,1,1)))}1' 

Hello world

or extending your solution

$ echo "hello world" | awk 'BEGIN{FS=""} {sub($1,toupper($1))}1'

Hello world

not rewriting $0 will preserve the original format.

karakfa
  • 66,216
  • 7
  • 41
  • 56