Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Parse data from a line to get 2 variables

by Sunnmann (Acolyte)
on May 12, 2006 at 23:48 UTC ( #549145=perlquestion: print w/replies, xml ) Need Help??

Sunnmann has asked for the wisdom of the Perl Monks concerning the following question:

Afternoon Monks!

For the life of me I have been searching for this
information for a while now. I am not good at perl (as
I have stated before), but still learning slowly as I
get the chance to use it.

What I need is to take information from a file, which I
know how to do with the code below.

open (LABELS, "labellist.txt") or die "I could not get at labellist.tx +t as input"; while (<LABELS>) { }
Now, labellist.txt has information like so:

LOT1 PRODUCT1 LOT2 PRODUCT1 LOT3 PRODUCT2 LOT4 PRODUCT3 LOT5 PRODUCT2
Those are tabs between the LOT and PRODUCT.
What I would like to do is somehow get each LOT# into
a variable $lotnumber and each PRODUCT# into a variable
$product.

A little more information:
LOT# will always be 8 characters long and be in the
format 1Letter followed by 7 Numbers or 8 Numbers
(Exs: F1234567, J1234567, 12345678). Product can range
from 6-9 characters and ussually start with a number
followed by 2 Letters then 3 numbers and most times at
the end have 2-3 letters (Exs: 4GT765, 4GT765HF,
6JK764BVD)

I have tried something like this but it is not working out!

my @Info; open (LABELS, "labellist.txt") or die "I could not get at labellist.tx +t as input"; while (<LABELS>) { chomp; if (m%E\n%) { print "$_\n"; print "\n"; @Info=$_; } }
What I get is not what I want when I test it by
printing out @info or trying to get $Info[0] and
$info[1]. the only thing in @Info is the whole line and the LOT
and PRODUCT dont go in the array as seperate entities.

Replies are listed 'Best First'.
Re: Parse data from a line to get 2 variables
by turo (Friar) on May 13, 2006 at 00:11 UTC
    I think you want something like this
    #!/usr/bin/perl use Dumpvalue; open (LABELS, "labellist.txt") or die "I could not get at labellist.tx +t as input"; my %info; while (<LABELS>) { my ($lot,$prod) = m/(\S+)\s+(\S+)/; $info{$lot} = $prod; } my $dumper = new Dumpvalue; $dumper->dumpValue(\%info);
    Anyway, i don't know what is exactly what you wanted to do with your code, it doesn't seem the same as the problem you're telling.
    perl -Te 'print map { chr((ord)-((10,20,2,7)[$i++])) } split //,"turo"'
      Sorry if I was not clear :)

      I have been approached by one of my customers to make an application
      (script) that will take input from a file and print labels for them so
      they do not have to enter them into the label printing program already
      made, one by one. It gets tedious for them to do this for 100 lots for
      instance.

      What I need to do then is get LOT1 into the variable $lot and PRODUCT1
      into the variable $prod. So while I have the loop going. I will then
      take these variables and put them into another string of code I have to
      output to a printer so they will print labels in a certain format with
      the lotnumber and productname on them.

      The format I will put this into to send to the printer is as follows:

      printCode = printCode & "^XA^LH30,30" & _ "^FO110,65^A0,N,100^FD" & _ lotNumber & "^FS" & _ "^FO150,160^BY2,3.0^B3N,N,125,N,N^FD" & _ lotNumber & "^FS" & _ "^FO75,375^A0,N,50,30^FD" & _ productName & "^FS" & _ "^FO30,425^BY2,2.0^B3N,N,50,N,N^FD" & _ productName & "^FS" & _ "^XZ" & vbNewLine

      I took this from teh main printing program that prints labels one at a
      time. I believe this was either written in VB or C something. I will
      have to substitute lotNumber for $lot and productName for $prod. Then
      find teh correct syntax to send this to the printer and I have what I
      need.

      I have been working on thsi still while waiting on a reply. Do you think
      this does it? (Gotta love it when you find the right words you were
      looking for to search on google) LOL

      #!c:\perl\bin my $printCode = ""; my $lotNumber; my $productName; my $Info; open (LABELS, "labellist.txt") or die "I could not get at labellist.tx +t as input"; while (<LABELS>) { chomp; if (m%E%) { # print "$_\n"; # print "\n"; $Info=$_; $lotNumber=substr($Info, 0,8); $productName=substr($Info, 9); # print "$lotNumber\n"; # print "$productName\n"; $printCode = "$printCode & \"\^XA\^LH30,30\" & _ \"\^FO110,65\ +^A0,N,100\^FD\" & _ $lotNumber & \"\^FS\" & _ \"\^FO150,160\^BY2,3.0\ +^B3N,N,125,N,N\^FD\" & _ $lotNumber & \"\^FS\" & _ \"\^FO75,375\^A0,N +,50,30\^FD\" & _ $productName & \"\^FS\" & _ \"\^FO30,425\^BY2,2.0\^B +3N,N,50,N,N\^FD\" & _ $productName & \"\^FS\" & _ \"\^XZ\" & vbNewLin +e"; print $printCode; } }

      Now I am not sure that the syntax to the $printCode is correct, but I
      will get that down to a T sooner or later.
        He actually gave you the answer, more or less:

        my ($lot,$prod) = m/(\S+)\s+(\S+)/;
        instead of:
        $Info=$_; $lotNumber=substr($Info, 0,8); $productName=substr($Info, 9);
        I'm not sure what you are doing with the if(m%E%), but I presume that is for testing...

        Devnul

        You might do well to ask your customer if they have the Programmer's Reference Manual for the printer. Some manufacturers ship one with every box; others sell them separately or make them available on their web site. In order to find this in the latter case, you'll need the exact make and model of the printer on which the labels will be printed.

        Of course, if the manufacturer regards this as a trade secret or something, you'll probably be going back to the reverse-engineering approach you've outlined above.

Re: Parse data from a line to get 2 variables
by jwkrahn (Monsignor) on May 13, 2006 at 03:53 UTC
    Based upon your specifications you probably want something like this:
    use warnings; use strict; open LABELS, '<', 'labellist.txt' or die "I could not get at labellist +.txt as input: $!"; while ( <LABELS> ) { my ( $lotnumber, $product ) = /^(\w\d{7})\t(\w{6,9})$/ or next; print "^XA^LH30,30^FO110,65^A0,N,100^FD$lotnumber^FS^FO150,160^BY2 +,3.0^B3N,N,125,N,N^FD$lotnumber^FS^FO75,375^A0,N,50,30^FD$product^FS^ +FO30,425^BY2,2.0^B3N,N,50,N,N^FD$product^FS^XZ\n"; } close LABELS;
      My initial thought was to use 'split' as suggested in an earlier reply. However, reading your solution certainly seems to be a better approach.
      I hadn't thought of using the min/max match. Good call!
        I thought I would show you all the conclusion I came up
        with thanks to your help. I used the solution to
        getting my variables originally posted by Turo, not
        my min/max as I had it. But here is the program in full.

        #!c:\perl\bin use warnings; use strict; my $lotNumber; my $productName; my $Info; my $choice; my $printLocal; my $printEcho; my $ftpobj; my $ftp; &MAIN; sub MAIN { print "Please make sure that you have all labels added into labellist. +txt\nin the correct format.\n\nLot number then a tab and then Product + Name for each line\n\nEXAMPLE\:\nE1234567\t2RZ563DA\nE2345678\t2RZ12 +8CA\nE3456789\t2RS128BB\n\n\n"; print " 1\: East QPS\n 2\: East TC\n 3\: West Etest\n 4\: West TC\n 5\ +: Quit\n What is your choice? "; $choice = <STDIN>; chomp ($choice); if ($choice==1) { $printLocal="10\.10\.10\.10"; $printEcho="East QPS Label Printer"; } elsif ($choice==2) { $printLocal="10\.10\.10\.11"; $printEcho="East TC Label Printer"; } elsif ($choice==3) { $printLocal="10\.10\.10\.12"; $printEcho="West TC Label Printer"; } elsif ($choice==4) { $printLocal="10\.10\.10\.13"; $printEcho="West Etest Label Printer"; } elsif ($choice==5) { system "CLS"; print "MultiPrint Has Shut Down."; exit 0; } else { system "CLS"; print "You have chosen an invalid Number, Please try again\n\ +n"; &MAIN; } print "Backing up old test.txt... \n"; rename ("Labels.txt", "test.bac") || die "Cannot rename Labels.txt +: $!"; open (LABELS, "labellist.txt") or die "I could not get at labellist.tx +t as input"; open (OUTPUT, ">>Labels.txt") or die "I could not get at Labels.txt as + ouput"; my %info; while (<LABELS>) { my $printCode = ""; my ($lotNumber,$productName) = m/(\S+)\s+(\S+)/; $info{$lotNumber} = $productName; # print "$lotNumber\n"; # print "$productName\n"; print OUTPUT "\^XA\^LH30,30\n\^FO110,65\^A0,N,100\^FD$lotNumbe +r\^FS\n\^FO150,160\^BY2,3.0\^B3N,N,125,N,N\^FD$lotNumber\^FS\n\^FO75, +375\^A0,N,50,30\^FD$productName\^FS\n\^FO30,425\^BY2,2.0\^B3N,N,50,N, +N\^FD$productName\^FS\n\^XZ\n"; } close LABELS; close OUTPUT; } print "You have chosen to print Labels.txt to the $printEcho ($printLo +cal).\n\n Sending to printer now.\n\n"; use Net::FTP; $ftpobj = Net::FTP -> new("$printLocal", Debug => 0) or die "Cannot connect to some.host.name: $@"; $ftpobj -> login("user","") or die "Cannot login ", $ftp->message; $ftpobj -> put ("Labels.txt") or die "put failed ", $ftp->message; $ftpobj -> quit; print `CLS`; &MAIN;
        This gives them a menu option that asks where they want it
        to be printed, then once they chose it is all good.
        It has been tested to work and print the labels
        as wanted. Once again, THANK YOU ALL!


        Of course all confidential info has been changed to
        protect my company :)
Re: Parse data from a line to get 2 variables
by Anonymous Monk on May 13, 2006 at 01:31 UTC
    You could also try :

    @labels = split /\t/, $_;

    Which splits a string into an array,
    breaking on the tab character, '\t'.

    Hopefully.

      May be better to use \s+ than \t,
      this will match one or more whitespace
      chars rather than just the one tab.
        or use the special split ' ', $line; behavior of split

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://549145]
Approved by kvale
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (1)
As of 2022-05-22 07:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (80 votes). Check out past polls.

    Notices?