Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BASH: importing data from flat file into template

I have a flat file of records, each 33 lines long. I need to format this file to specs in a template. The template is in DOS format while the source file is in NIX format. The template has specific indenting and spacing which must be adhered to. I've thought of a few options:

  • BASH with classic nix tools: sed, awk, grep etc...
  • BASH with template toolkit
  • Perl eith template toolkit
  • Perl

These are in order of my familiarity. Here's a sample source record ( NIX format ): I've reduced the number of newlines to save space ( normally 33 lines ):

JACKSON HOLE SANITARIUM AND REPTILE ZOO
45 GREASY HOLLER LN
JACKSON HOLE, AK   99999


Change Service Requested


BUBBA HOTEP
3 DELIVERANCE RD
MINNEAPOLIS, MN   99998


BUBBA HOTEP 09090909090909

You have a hold available for pickup as of 2012-01-04:

Title: Banjo for Fun and Profit
Author: Williams, Billy Dee
Price: $10 

Here's the template ( DOS format -- lines reduced - 66 lines normally):

     <%BRANCH-NAME%>
     <%BRANCH-ADDR%>
     <%BRANCH-CTY%>


<%CUST-NAME%> <%BARCODE%>
You have a hold available for pickup as of <%DATE%>:

Title: <%TITLE%>
Author: <%AUTHOR%>
Price: <%PRICE%>


             <%CUST-NAME%>
             <%CUST-ADDR%>
             <%CUST-CTY%>

end of file

It actually does say "end of file" at the end of each record.

Thoughts? I tend to over-complicate things.

UPDATE2

Figured it out.

My answer is below. Feel free to suggest improvements.

like image 391
Bubnoff Avatar asked May 15 '26 04:05

Bubnoff


1 Answers

As a starter, here is a hint: Perl HERE-documents (showing just a few substitutions as a demo):

#!/usr/bin/perl
use strict;
use warnings;

my @lines = qw/branchname cust_name barcode bogus whatever/; # (<>);

my ($branchname, $cust_name, $barcode, undef, $whatever) = @lines;

print <<TEMPLATE;
     $branchname
     <%BRANCH-ADDR%>
     <%BRANCH-CTY%>


$cust_name $barcode
You have a hold available for pickup as of <%DATE%>:

Title: <%TITLE%>
Author: <%AUTHOR%>
Price: <%PRICE%>


             $cust_name
             <%CUST-ADDR%>
             <%CUST-CTY%>

end of file
TEMPLATE

Replace the dummy input array with the lines read from the stdin with (<>) if you will. (Use a loop reading n lines and push it to the array if that is more efficient). I just showed the gist, add more variables as required, and skip input lines by specifting undef for the 'capture' variable (as shown).

Now, simply interpolate these variables into your text.

If line-ends are giving you any grief, consider using chomp eg.:

my @lines = (<>); # just read em all...
my @cleaned = map { chomp } @lines;
like image 70
sehe Avatar answered May 17 '26 18:05

sehe