If you have a question on how to do something in Perl, or you need a Perl solution to an actual real-life problem, or you're unsure why something you've tried just isn't working... then this section is the place to ask. Post a new question!

However, you might consider asking in the chatterbox first (if you're a registered user). The response time tends to be quicker, and if it turns out that the problem/solutions are too much for the cb to handle, the kind monks will be sure to direct you here.

User Questions
greedy subexpression between two nongreedy ones
2 direct replies — Read more / Contribute
by raygun
on Jun 02, 2015 at 00:32

    I am performing a substitution on strings that fall between two anchors. A certain substring -- say, "cd" -- may or may not appear as part of the string I'm matching. If it does, I need to capture it.

    In my examples below, the anchors are commas, but in reality they are complex regular expressions, so that I can't just use [^,]* to avoid steamrolling over them.

    In essence, the substitution will be some variation on

    s/,.*(cd)?.*,/=$1=/

    Making the two .* subexpressions nongreedy while keeping the (cd)? greedy would seem to express exactly what I'm trying to do, except for the slight inconvenience that it doesn't work:

    echo ,abcdefg,abcdefg | perl -pe 's/,.*?(cd)?.*?,/=$1=/'

    I want a captured "cd" between the two equal signs, but the $1 remains empty. The problem seems to be that .*? is apparently not merely nongreedy but also unaccommodating: It won't even consume enough to allow the following greedy subexpression to match. It's not clear to me why a nongreedy expression would consume enough to match a required subexpression (i.e. if I omitted the ? after (cd)), but not an optional but greedy one.

    I can make the expression capture the "cd" if I make my first subexpression a little more explicit:

    echo ,abcdefg,abcdefg, | perl -pe 's/,(?:(?!cd).)*(cd)?.*?,/=$1=/'

    This gives me the desired output of "=cd=abcdefg,". But this fails if the part between the anchors does not contains a "cd":

    echo ,abcefg,abcdefg, | perl -pe 's/,(?:(?!cd).)*(cd)?.*?,/=$1=/'

    Here, the desired output is "==abcdefg,", but the greedy subexpression ignores the anchor boundary and goes into the section of the string following it to find a "cd".

    I've tried various other things but not yet found something that works. How do I get the $1 to be populated with a "cd" if it appears in the string, and remain empty if it doesn't, while staying between the anchors?

why does location of function matter?
5 direct replies — Read more / Contribute
by smartyollie
on Jun 01, 2015 at 17:54
    I have run into a situation several times at my current job where the location of a perl function affects whether it works or not. I've never had this happen before and feel like I'm missing something obvious. The current scenario happens on both Windows (Strawberry Perl) and UNIX (Solaris v5.8.4). I have a function called PostValidate with one argument. When I put the function definition AFTER the main body of code, it runs; when I put the function before, it fails with

    Too many arguments for main::PostValidate at y.pl line 349, near "$ofile)"

    The call within the main body looks like this:

    if ($validate) {
    PostValidate($ofile);
    }

    I don't have any prototypes defined and I'm really at a loss as to why it should matter where the function is. Any ideas?
why aren't I see the hash while using dump?
2 direct replies — Read more / Contribute
by perlynewby
on Jun 01, 2015 at 17:08
    I don't seem to understand what is going on here with "dump" module. I expect to see the HASH but only returns the last key, value...why?what am I missing? please help me understand. <data> uno = uno due = dos tre = tres quattro = quatro cinque = cinco <\data> <code> use strict; use warnings; use Data::Dump qw(dump); my %hash; open my $in, '<',"./test_data.txt" or die ("can't open the file:$!\n"); my $data; while (<$in>){ chomp; %hash= split (/\s*=\s/); #dump \%hash; #checking on what's being assigned to hash } close $in; #print "this is the data\n"; dump \%hash; <\code>
Perl Array output Help
3 direct replies — Read more / Contribute
by PerlCramps
on Jun 01, 2015 at 14:59
    I created the perl script below It consist of multiple subroutines collecting seperate information. I am having a problem managing the array output scalar, I would like to see a different line input for each command and each host. This is the part as a beginner I having problem with. The hosts.txt file havng (server1, server2, server30 and the commands are one, two, three, four. Please help. #!/usr/bin/perl use 5.010; use strict; use warnings; main(@ARGV); sub get_host # Collect the host name from a text file { open(HOST, '<', 'hosts.txt') or error("cannot open file ($!)"); my @host = <HOST>; return "@host\n"; } sub get_logon # Collect logon ID from keyboard { my $logon; print "Please Enter Logon ID:\n"; chomp ($logon =<>); return $logon; } sub get_psswd # Collect password from keyboard { my $psswd; print "Please Enter Password for hostID:\n"; chomp ($psswd =<>); return $psswd; } sub get_command # Collect the commands from a text file { open(CMD, '<', 'cmds.txt') or error("cannot open file ($!)"); my @cmd = <CMD>; return @cmd; } sub main # Command execution and export data to local file { my @host = get_host(); print @host; print "\n"; my $logon = get_logon(); print $logon; print "\n"; my $psswd = get_psswd(); print $psswd; print "\n"; my @cmds = get_command(); print @cmds; my $output = qx(cmd); open my $OUTPUT, '>>' , 'devbfs51chassisshow.txt' or die " Couldn't open output.txt: $!\n"; print "1plink -ssh -pw $psswd -l $logon @host @cmds"; }
backslash c (\c) on EBCDIC
1 direct reply — Read more / Contribute
by zatlas1
on Jun 01, 2015 at 14:46
    The \c pattern is defined on ASCII environments this way: "control-x", where x is any character The precise effect of "\cx" is as follows: if "x" is a lower case letter, it is converted to upper case. Then bit 6 of the character (hex 40) is inverted. Thus "\cz" becomes hex 1A, but "\c{" becomes hex 3B, while "\c;" becomes hex 7B. How should this behave on EBCDIC platforms, like Perl-mvs Thanks ZA
Why to wrap Perl classes inside a Perl script into blocks
3 direct replies — Read more / Contribute
by capfan
on Jun 01, 2015 at 12:50

    Dear all,

    I just had a look at the script here: http://www.perlmonks.org/?node_id=1023430.
    In the Perl script, all Perl classes are wrapped in a code block.

    Why?

    I'd guess it's to make sure that the scopes don't mix. But isn't this already done by using another name space?

    Thanks all

Serial communication between perl and arduino
4 direct replies — Read more / Contribute
by perl_sck_58
on Jun 01, 2015 at 11:32

    Hi Monks, I am trying to setup a serial communication between arduino uno and pc using Perl. I am using Win32::SerialPort module for the same

    The problem is I am not able to read or write to the arduino In config.pl file I am saving the settings to conf.cfg file and in serial.pl I am trying to write to arduino

    Config.pl

    use strict; use Win32::SerialPort; my $ob = Win32::SerialPort->new ('COM22') || die; $ob->baudrate(9600); $ob->parity("none"); $ob->parity_enable(1); # for any parity except "none" $ob->databits(8); $ob->stopbits(1); $ob->handshake('none'); $ob->buffers(4096, 4096); $ob->write_settings || die "cant write settings"; $ob->save("conf.cfg"); print "wrote configuration file conf.cfg\n";

    Serial.pl

    use strict; use Win32::SerialPort 0.11; my $ob = Win32::SerialPort->start ("conf.cfg") || die; $ob->write("abc"); $ob->write("xyz"); undef $ob;

    After running this code I get a message that "Second Write attempted before First is done at Simple_serial_com.pl line 10. Use of uninitialized value $written in numeric ne (!=) at C:/Perl64/site/lib/Win 32/SerialPort.pm line 1580."

    In the arduino program I am just waiting to receive for any serial data

    void setup() { pinMode(13,OUTPUT); Serial.begin(9600); } void loop() { if(Serial.available()) { pinMode(13,HIGH); } }

    I also tried adding a delay between the two serial writes in the perl program, but also got the same error message.

    Please let me know if I need to do any other configurations or if I am doing something wrong

    Thanks all

Simple but not elegant ?
5 direct replies — Read more / Contribute
by matthew_t_dooley
on Jun 01, 2015 at 11:23

    I have an EDI file to examine, ascii files with records starting "H00", "H01" for header records and "D01"..."D99" for detail records. I want to process each "H00".."D99" block at a time and have used

    $/="\nH00"

    In order to extract the "H01" records from this set, I have used

    $_ =~ /(\nH01)(.*)(\n)/ ; my $H01record="H01".$2 ;

    then checking the "H01" record, as follows

    if ( substr ($H01record,43,2) eq "SA" ) ...

    Is this very ugly? Is there a more elegant way to do it?
    Please do not laugh, this is serious

e-mail fails with address that is not a fully qualified domain
4 direct replies — Read more / Contribute
by merrymonk
on Jun 01, 2015 at 11:21
    I am trying to send a test e-mail with the following Perl script.
    use strict; use warnings; use MIME::Entity; my $From = '<valid e-mail address>'; my $To = '<valid e-mail address>'; my $Subject = 'Test'; my $Type = 'text/plain'; my $Host = 'mail.btinternet.com'; my $msg = MIME::Entity->build( From => $From, To => $To, Subject => $Subject, Type => $Type, Data => 'This is a test message', Debug => 1 ); print "\nbefore smtpsend\n\n"; my @ok = $msg->smtpsend( Host => $Host, To => $To, Debug => 1 ); if (@ok) { print "Sent message to: ", join(', ', @ok), "\n"; } else { print "\nFailed to send message"; }
    I am fairly sure that something very similar worked on my system some years ago. However, since then I have:
    1. started to use Thunderbird as my e-mail application;
    2. started to use Virgin Media to give broadband and internet services but I have retained by bt e-mail address.
    Using this script I get the following output.

    before smtpsend

    Net::SMTP>>> Net::SMTP(2.31)
    Net::SMTP>>> Net::Cmd(2.29)
    Net::SMTP>>> Exporter(5.68) )
    Net::SMTP>>> IO::Socket::INET(1.33) )
    Net::SMTP>>> IO::Socket(1.37) )
    Net::SMTP>>> IO::Handle(1.34) )
    Net::SMTP=GLOB(0x25d4468)<<< 220 rgout03.bt.lon5.cpcloud.co.uk ESMTP Service ready)
    Net::SMTP=GLOB(0x25d4468)>>> EHLO localhost.localdomain)
    Net::SMTP=GLOB(0x25d4468)<<< 250-rgout03.bt.lon5.cpcloud.co.uk)
    Net::SMTP=GLOB(0x25d4468)<<< 250-DSN)
    Net::SMTP=GLOB(0x25d4468)<<< 250-8BITMIME)
    Net::SMTP=GLOB(0x25d4468)<<< 250-PIPELINING)
    Net::SMTP=GLOB(0x25d4468)<<< 250-AUTH=LOGIN)
    Net::SMTP=GLOB(0x25d4468)<<< 250-AUTH LOGIN PLAIN)
    Net::SMTP=GLOB(0x25d4468)<<< 250-DELIVERBY 300)
    Net::SMTP=GLOB(0x25d4468)<<< 250 SIZE 41943040)
    Net::SMTP=GLOB(0x25d4468)>>> MAIL FROM:<postmaster@hm-insp15>)
    Net::SMTP=GLOB(0x25d4468)<<< 553 <postmaster@hm-insp15> Invalid mail address, must be fully qualified domain)
    Net::SMTP=GLOB(0x25d4468)>>> QUIT)
    Net::SMTP=GLOB(0x25d4468)<<< 221 rgout03.bt.lon5.cpcloud.co.uk QUIT)

    Failed to send message

    It seems that postmaster@hm-insp15 is not correct. What can I do to correct this?
Expect.pm spawn for exporting evn variables
2 direct replies — Read more / Contribute
by anilfunde
on Jun 01, 2015 at 10:02
    I am writing cvs utility for our internal project. I want to export cvsroot for same. i tried below code
        $Expect::Debug = 1;
        $Expect::Log_Stdout = 1;
        $Expect::Exp_Internal = 1;
    
        my $cvs_root  = 'export CVSROOT=:pserver:user11@10.x.x.X:/export/DEMO' . "\r\n";
        my $echo_cmd = "echo \$CVSROOT \r\n";
        
        
        #cvs, give me a token
        my $shell_obj = new Expect or die "Couldn't spawan a process : $!\n";
        
        #pty return all sends itself as it is. Making your reposnse unpredictable. Get it corrected
        $shell_obj->raw_pty(1);
    
        $shell_obj = Expect->spawn("$cvs_root") or die "Couldn't start a program: $!\n";
    
    
    while spawning process to export CVSROOT, i am getting this error when executing this script
    Cannot exec(export CVSROOT=:pserver:user11@10.x.x.x:/export/demo
    ): Permission denied
    
    
    Not sure what i am missing here. Monks could you please give me hint or direction to walk on.

Add your question
Title:
Your question:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":


  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.