1

I have a .txt file and I need to add commas as decimal separators to improve the readability. Those long numbers only exist in certain columns and I couldn't find a way to do that. The columns are separated by semicolons and can contain any character. I thought about using an if statement in awk to check if the length of those columns are bigger than 3, but then I couldn't find a way to put the commas in between every three digits. The numbers are in the third and fourth columns.

This

BitstreamCyberCJK;Freeware;30275;28686;v2.0 beta (1998-03-17);Cyberbit.ttf (12.4 MB);Bitstream CyberCJK;Medium (Normal), Book, Roman;TTF;Cove

Y.OzFontN;Freeware;21957;57621;v13.00 sfnt rev 5 Pen-Ji (2010-08-24);YOzRN.TTC (13.5 MB);YOzFontN;Regular;TTC;Any

should turn into this:

BitstreamCyberCJK;Freeware;30,275;28,686;v2.0 beta (1998-03-17);Cyberbit.ttf (12.4 MB);Bitstream CyberCJK;Medium (Normal), Book, Roman;TTF;Cove

Y.OzFontN;Freeware;21,957;57,621;v13.00 sfnt rev 5 Pen-Ji (2010-08-24);YOzRN.TTC (13.5 MB);YOzFontN;Regular;TTC;Any
3
  • The number are always 5 digits long? – schrodigerscatcuriosity Oct 29 '19 at 18:28
  • No, they can be shorter or longer – arty Oct 29 '19 at 18:32
  • Actually, I checked the file and the numbers are either 4 or 5 digit long. – arty Oct 29 '19 at 18:57
3

If you have numfmt from GNU Coreutils, and your locale supports such grouping, you could use:

numfmt -d ';' --field=- --grouping --invalid='ignore' < file

Ex.

$ numfmt -d ';' --field=- --grouping --invalid='ignore' < file
BitstreamCyberCJK;Freeware;30,275;28,686;v2.0 beta (1998-03-17);Cyberbit.ttf (12.4 MB);Bitstream CyberCJK;Medium (Normal), Book, Roman;TTF;Cove

Y.OzFontN;Freeware;21,957;57,621;v13.00 sfnt rev 5 Pen-Ji (2010-08-24);YOzRN.TTC (13.5 MB);YOzFontN;Regular;TTC;Any

If you know which fields contain the numeric fields, you can specify them explicitly and omit the --invalid handling:

numfmt -d ';' --field=3,4 --grouping < file

If you have GNU awk, you can do a similar thing using the %' format modifier with sprintf:

gawk '
  BEGIN {OFS=FS=";"} 
  {for(i=1;i<NF;i++) {if($i ~ /^[0-9]+$/) $i = sprintf("%'\''d", $i)}} 
  1
' file
1
  • Can it be done by awk, I don't have GNU awk – arty Oct 29 '19 at 18:54

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.