I have data was collected and saved in file "data.txt", in the following format:

<$ MG_nr>
</200>company-type:Engine1
</210>company-name:STR
</220>address:XX
</230>nr:4568789
</240>zipcode:08765
</250>place:ljkmljubi
</260>phone:786754678
</270>fax:76756778
</$>
<$ MG_nr>
</280>company-type:Engine2
</290>company-name:STR
</300>address:XX
</310>nr:7675678
</320>zipcode:87867
</330>place:jkhgkl
</340>phone:87865
</350>fax:876578
</$>
<$ MG_nr>
</360>company-type:Engine3
</370>company-name:STR
</380>address:XX
</390>nr:78675467
</400>zipcode:87657
</410>place:uiytryui
</420>phone:87656788976
</430>fax:8976535467
</$>
<$ MG_nr>
</440>company-type:Engine4
</450>company-name:STR
</460>address:XX
</470>nr:876578y67
</480>zipcode:786578
</490>place:kljhgryui
</500>phone:8976546789
</510>fax:989765
</$>

I wanted to turn this to a spreadsheet like this:

Type         Name   Address   Nr      Zipcode Place     Phone       Fax
------------------------------------------------------------------------
Engine1      STR     XX      4568789  08765   ljkmljubi 786754678   76756778
Engine2      STR     XX      7675678  87867   jkhgkl    87865       876578
Engine3      STR     XX      78675467 87657   uiytryui  87656788976  8976535467
Engine4      STR     XX      87657867 786578  kljhgryui 8976546789 989765

I tried this code which I found it on U & L site, and I tried to replicate it:

#!/bin/bash
cut -d'>' -f 2 data.txt | awk -F: '
/^company-type:/{type[c]=$2}
/^company-name:/{name[c]=$2}
/^address:/{address[c]=$2}
/^nr:/{nr[c]=$2}
/^zipcode:/{zipcode[c]=$2}
/^place:/{place[c]=$2}
/^phone:/{phone[c]=$2}
/^Fax:/{fax[c]=$2;c++}
END {
 print "Type         Name   Address   Nr Zipcode Place Phone Fax"
 print "------------------------------------------------------------------------"
 for(x in type) {
  printf "%-10s %3d    %s      %s %s %s %s %s\n",
    substr(type[x],2),
    company-name[x],
    address[x],
    nr[x],
    zipcode[x],
    place[x]
    phone[x]
    fax[x]
 }
}' data.txt

But this didn't work, it only prints the header!!!

print "Type         Name   Address   Nr Zipcode Place Phone Fax"
 print "------------------------------------------------------------------------"

I can't figure out what I am doing wrong?

I appreciate any advice! or any suggestion to make the code above works and simpler.

This is a simpler solution:

awk -F'[>:]' 'BEGIN{print "company-type company-name address nr zipcode place phone fax"}{print $3}' data.txt | xargs -n8 | column -t

company-type  company-name  address  nr        zipcode  place      phone        fax
Engine1       STR           XX       4568789   08765    ljkmljubi  786754678    76756778
Engine2       STR           XX       7675678   87867    jkhgkl     87865        876578
Engine3       STR           XX       78675467  87657    uiytryui   87656788976  8976535467
Engine4       STR           XX       87657867  786578   kljhgryui  8976546789   989765

The field separator -F enables awk to read the data in columns based on : and >, then awk prints the third column which is equivalent to the required actual data, at the same time it constructs the header.

This output is piped to xargs which reorganizes it under eight columns. Finally, the command column adds tabs and equal spaces between the resultant columns.

While Goro has provided a nice solution, for better understanding, I thought I'd point out some issues with your code that keep it from running correctly:

  • You collect the data indexing on the variable c, but you never change its value. You would only ever get the last data read from this code. All earlier data would be overwritten. An easy fix for this would be to change /^company-type:/{type[c]=$2} to /^company-type:/{type[++c]=$2}.
  • When you print the company type field, for no apparent reason, you are stripping the first character off of it: substr(type[x],2), would produce "ngine1", not "Engine1" (assuming that there is no unprintable character in your data that actually was being stripped off).
  • This is probably the reason you see no output: you need to add commas after place[x], phone[x]. When printf doesn't find a comma after place[x], it assumes that is the last of its arguments, which leaves it 2 arguments short of the the 8 required by the format statement. That produces a syntax error, which stops the script. I don't know why you didn't get the syntax error message, though.

Even with these corrections, this code is particularly fragile. Even a minor variation of formatting would cause it to fail.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.