Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Seekers of Perl Wisdom

( #479=superdoc: print w/replies, xml ) Need Help??

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
parse multiple text files keep unique lines only
4 direct replies — Read more / Contribute
by Anonymous Monk
on Jun 27, 2017 at 15:33

    Hi Monks, who are always smarter than me. I'm trying to use the following code but rather than modify just one file to contain only unique lines I'm trying to modify many files in a directory.

    I've successfully erased my data 5 times with some not so successful modifications so far so I'm seeking some wisdom. Here's the first bit of code:

    #!/usr/bin/perl w open(INF,"db.txt"); @data = <INF>; close(INF); @sd = sort(@data); for(@sd){ push @out, $_ if (not @out) or ($out[-1] ne $_); }; open(OUTF,">outdb.txt"); print OUTF; close(OUTF);

    I'm pretty sure I'm overthinking it and the solution is very, very simple. Here's my code to find the files. See below. I just can't seem to get the two bits of code together properly.

    #find the files I want to change my @files; find( sub { return unless -f; # Files only return unless /\.txt$/; # Name must end in ".txt" push @files, $File::Find::name; }, $directory );
Very Odd Issue When Using pp to Create an .exe File Including Date::Calc
3 direct replies — Read more / Contribute
by perldigious
on Jun 27, 2017 at 10:46

    I figured out how to fix an issue I first had shortly after I began programming in Perl and that has plagued me since, but I'm at a loss to explain how this could possibly matter. This is definitely one for Monks more knowledgeable than I, and especially (I presume) those familiar with the pp module. I'm using Strawberry Perl on Windows 7, and of course can provide more information than that if necessary. I simply enter pp -o my_name.exe on the command line.

    When I have the following code and and am trying to use pp to make an .exe, it makes the .exe, but the .exe doesn't seem to do anything at all when run (it won't even pause on the my $pause_here = <STDIN> line here.

    #!/usr/bin/perl use utf8; use 5.022; use strict; use List::Util qw(max); use Date::Cal +c qw(Delta_Days); say "FINISHED"; my $pause_here = <STDIN>;

    However, when I do the following, it works just fine, makes the .exe, and the .exe runs and performs as expected. Yes, the only difference is the one newline after use 5.022.

    #!/usr/bin/perl use utf8; use 5.022; use strict; use List::Util qw(max); use Date::Calc qw(Delta_Days); say "FINISHED"; my $pause_here = <STDIN>;

    It's the use Date::Calc qw(Delta_Days) that always caused me trouble. Without it, and even with all the other use statements on a single line, it also all works perfectly fine.

    #!/usr/bin/perl use utf8; use 5.022; use strict; use List::Util qw(max); say "FINISHED"; my $pause_here = <STDIN>;

    Am I crazy? Can anyone else repeat this behavior or explain it?

    Now I always put one use statement per line anyway, but I had this problem in several old scripts I wrote where I wasn't yet in that habit, and I never found this as the "fix" until now. This plagued me so much until now that I literally have written and rewritten (because of course it didn't work the first time I reinvented the wheel) my own days_diff subroutine and simple single day difference test of it to deal with this.

    use utf8; use 5.022; use strict; use warnings; for (my $year=1970; $year<=2100; $year++) { for (my $month=1; $month<=12; $month++) { for (my $day=1; $day<=31; $day++) { next if ( ($month == 2 && ($day == 30 || $day == 31)) || ($month == 2 && $day == 29 && ($year%4 != 0 || ($year +%100 == 0 && $year%400 != 0))) || ($month == 4 && $day == 31) || ($month == 6 && $day == 31) || ($month == 9 && $day == 31) || ($month == 11 && $day == 31) ); my $date1 = $month. "/" . $day . "/" . $year; my $date2 = $month . "/" . ($day+1) . "/" . $year; $date2 = ($month+1) . "/1/" . $year if ( ($day+1 == 32) || ($month == 2 && ($day+1 == 30 || $day+1 == 31)) || ($month == 2 && $day+1 == 29 && ($year%4 != 0 || ($ye +ar%100 == 0 && $year%400 != 0))) || ($month == 4 && $day+1 == 31) || ($month == 6 && $day+1 == 31) || ($month == 9 && $day+1 == 31) || ($month == 11 && $day+1 == 31) ); $date2 = "1/1/" . ($year+1) if ($month+1 == 13 && $day+1 +== 32); my $difference = days_diff($date2, $date1); say "$date1\t$date2\t$difference" if ($difference != 1); } } } say "Hit Enter to quit."; my $pause = <STDIN>; sub days_diff { my ($month1, $day1, $year1) = split /\//, $_[0]; my ($month2, $day2, $year2) = split /\//, $_[1]; # The Date::Calc module function "Delta_Days" was used for this an +d worked great, but it would not compile in to an .exe using pp. # use Date::Calc qw(Delta_Days); # use is here for convenient copy +/paste # return Delta_Days($year2, $month2, $day2, $year1, $month1, $day1 +); # This crude (not precise over long timeframes or short ones spann +ing the end of February and March, but this was fine for the applicat +ion) method was used for a long time, # but it fails (in an unacceptable way) when subtracting a day tha +t falls on the 1st of the next month from a day that falls on the 31s +t the prior month (gives -0, not -1), # return sprintf("%.0f", ($year1-$year2)*365.25+($month1-$month2)* +365.25/12+($day1-$day2)); # Here a Gergorian calendar date to Julian day number conversion i +s used on both dates and then they are subtracted. # +egorian_calendar_date_to_Julian_day_number use POSIX qw(floor); # use is here for convenient copy/paste my $a1 = floor((14-$month1)/12); my $a2 = floor((14-$month2)/12); my $y1 = $year1 + 4800 - $a1; my $y2 = $year2 + 4800 - $a2; my $m1 = $month1 + 12*$a1 - 3; my $m2 = $month2 + 12*$a2 - 3; my $JDN1 = $day1 + floor((153*$m1+2)/5) + 365*$y1 + floor($y1/4) - + floor($y1/100) + floor($y1/400) - 32045; my $JDN2 = $day2 + floor((153*$m2+2)/5) + 365*$y2 + floor($y2/4) - + floor($y2/100) + floor($y2/400) - 32045; return $JDN1-$JDN2; }

    Just another Perl hooker - But the purist monks keep telling me I should do it for love, not money.
reading files in @ARGV doesn't return expected output
8 direct replies — Read more / Contribute
by fasoli
on Jun 26, 2017 at 19:04

    Hello again Wise Monks,

    I'm trying to read multiple files using @ARGV and then split them into columns and print the matrices. Then (if this ever works - I'm desperate at this point) I hope to do maths on the matrices. I have added comments at relevant places in the code, where I'm focusing my attention to solve my three problems - described further down.

    I've tried all day to create a short self-contained example with dummy data but my skills are more limited than I thought - facing compilation errors literally all day and now at midnight I've given up. In that case and because I'm desperate for some feedback, I have just posted my code as it is. I hope you can find a few minutes and take a look.

    My problems are three:

    1. intuitively, I would think that the two for loops should enclose the whole code and close at the very end of the script. However when I did that, printing @ARGV returned wrong results. When I closed the for loops right after pushing into @ARGV, then printing @ARGV returned the correct result. Any explanation of this behaviour would be greatly appreciated, I can't figure it out at all.

    2. print "@columns \n"; prints all files BUT ignores $nextUnless. Why?

    3. print "$list[$a][$b] "; prints only first file and nothing else

    . Does that mean that it's ignoring what's in @ARGV?

    I would appreciate any pointers and I apologise for the lack of a proper example. Any feedback / insights would be immensely appreciated, Thank you so much in advance.

    #!/bin/perl/ use strict; use warnings; my $molec1 = "molec1"; my $molec2 = "molec2"; my $input1; my $input2; @ARGV = ();; my $i; my $j; my $path = "/store/group/comparisons"; my $line; my @columns; my $nextUnless = 2; # nr of lines to skip my $CountLines = 0; # total nr of lines in all files for ($i=1; $i<=3; $i++) { open $input1, '<', "$path\/File-${molec1}-cluster${i}.out" or die $! +; push @ARGV, "$path\/File-${molec1}-cluster${i}.out"; } for ($j=1; $j<=2; $j++) { open $input2, '<', "$path\/File-${molec2}-cluster${j}.out" or die +$!; push @ARGV, "$path\/File-${molec2}-cluster${j}.out"; } print "@ARGV \n"; # for testing; indeed correct files are printed ## now split and print my @list; my $list; my $a; my $b; while ($line = <>) { $CountLines += 1; next unless $. > $nextUnless; chomp $line; $line =~ s/^\s+|\s+$//g; push @list, [split/\s+/, $line]; @columns = split /\s+/, $line; print "@columns \n"; ## problem: prints all columns from specifi +ed files but ignores the $nextUnless specification - why? } close $input1; close $input2; for ($a=0; $a<=$#columns; $a++) { for ($b=0; $b<=$#columns; $b++) { print "$list[$a][$b] "; ## problem: prints only first file ($i +=1) } print " \n"; }
textual GUI using only part of the terminal
3 direct replies — Read more / Contribute
by morgon
on Jun 26, 2017 at 18:27

    I have a very basic understanding of curses to build full-screen text GUIs, but I cannot figure out if it is possible to build a text-based GUI in Perl that only uses part of the terminal screen estate.

    What I mean is something like the "fzf" tool (which is written in go) does. Usually it takes over the whole terminal, but when supplying an argument like "--height 50%" it only takes a part of the terminal screen size, but within that part there is a GUI.

    Is is possible to do something like that in Perl (using curses or something else)?

    Many thanks.

Delay in Writing the data to Text file
5 direct replies — Read more / Contribute
by Preetham
on Jun 26, 2017 at 12:25

    Hi i have a below program to compare two file and log the result in new file. Its taking more than 10 min to log the data to AuditNew.txt file. br.1 file have around 3 lakh lines and MSMLogs.txt will have around 7,000 line.

    Is there is any way to get the result logged faster in AuditNew.txt.

    Note : Below print is displayed in console every 1 seconds for each line. it means the processing is faster but writing the data to text file is getting delayed.

    print("\nnumber of occurance is $count\n"); #!/usr/bin/perl use 5.010; use strict; use warnings; #Open MSM Log in read Mode open(my $MSMLog, '<','MSMLogs.txt'); #Create Audit txt file in write mode open(my $Audit, '>','br.1'); print("Task Started.........\n"); #iterate each word to identify the logs while (my $row = <$MSMLog>) { chomp $row; getCount($row); } sub getCount { #Open MobileService.log file in read mode open(my $MobileServiceLog, '<','one.txt'); my @StaticLog = @_; my $count = 0; #print ("\nvalue in MSM Static is ------ $StaticLog[0]\n"); while (my $row = <$MobileServiceLog>) { my @actualWord = split /;/, $row; my $MobileService = $actualWord[7]; #print ("value in MobileService is ------ $MobileService\n"); if ($MobileService =~ /$StaticLog[0]/) { $count += 1; } } $_=1 print ($Audit "\n$StaticLog[0] occurance is ------- \t$count\n"); print("\nnumber of occurance is $count\n"); close $MobileServiceLog; } print ($Audit "Task Completed"); print ("Task Completed"); close $MSMLog; close $Audit;
LibXML setNodeName error
1 direct reply — Read more / Contribute
by geddie2001
on Jun 26, 2017 at 10:48

    I am attempting to write a perl script that reads an xsl document and changes every instance of <xsl:element name =" foobar"> to <foobar> (essentially stripping out the `xsl:element name` so that the code is easier to read)

    Here is what I have in `test.xsl`:
    <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl=" +ansform"> <xsl:element name="foo"> <xsl:value-of select="bar"/> </xsl:element> </xsl:stylesheet>
    In ``:
    use strict; use warnings; use XML::LibXML; my $reader = XML::LibXML->load_xml(location => "test.xsl") or die "can +not read input file\n"; my $xpath_context = XML::LibXML::XPathContext->new($reader); foreach my $element_node ($xpath_context -> findnodes('//xsl:element') +) { my @attributes = $element_node -> attributes(); $element_node -> setNodeName($attributes[0]); }
    The output when I run this script is:  bad name at line 12 Any help would be greatly appreciated
creating and Deleting a new cookie
2 direct replies — Read more / Contribute
by tsdesai
on Jun 26, 2017 at 10:30

    I am trying to create a new cookie and then delete it later after certain actions. Below is my code that i create cookie

    use strict; use CGI; my $q = new CGI; my $cookie = $q->cookie(-name=>'pass', -value=>'xxxx', -expires=>'+1h', -path=>'/'); print $q->header(-cookie=>$cookie);

    The above is the pretty much standard code, but the cookie doesn't gets send to the browser. I am not sure why the cookie isn't created. I am going nuts something probably i am missing something silly. I have set the cookies before in different places but not sure why it doesn't work .

    Appreciate any help. Thanks, Teju
Warnings using -w
3 direct replies — Read more / Contribute
by Anonymous Monk
on Jun 26, 2017 at 10:07
    Hi Monks!

    This test script is to ask what would be an alternative and why I get this warning message:
    Use of uninitialized value $_[0] in string eq at /usr/local/share/perl5/ line 2209. if I use "-w".
    If I remove the "-w" and use instead "use warnings" I don't get the warning, is it because of been deprecated?
    The version of Perl I have is v5.10.1
    Any suggestions?
    #!/usr/bin/perl -w use strict; use CGI qw(:standard); use CGI::Carp qw( fatalsToBrowser set_message ); my $q = new CGI; print $q->header(); my $msg = escapeHTML( scalar $q->param( 'msg' )) || 'No Msg'; my $error = escapeHTML( scalar $q->param( 'error' )) || ' No error'; my $error_msg = ($msg) ? $msg : ($error) ? $error : ''; print "<br><br>Msgs: $error_msg <br><br>"; exit;

    Thanks for looking!
Issue getting value from text file and keep decimal
4 direct replies — Read more / Contribute
by jason.jackal
on Jun 26, 2017 at 10:07
    Folks I am trying to make an application that will loop over each line in a text file, and format output. However, the first line is dropping the decimal. Looking for some ideas on how to fix this and explain what is going on. I created my working copy in Python; however, I really want to learn Perl over Python.
    #!/usr/bin/perl #checkbook #2017-06-20 ## This app will create a general ledge sub format_value { local $_ = shift; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; return $_; } $item_date = "DATE"; $item_description = "DESCRIPTION"; $item_account = "ACCOUNT"; $item_debit = "DEBIT"; $item_credit = "CREDIT"; $item_balance = "BALANCE"; $blank_debit = " "; $blank_credit = " "; open (file_read, "input-checkbook.txt"); open (file_write, ">checkbook.txt"); sub runScript { $main_balance = 0.00; $format_main_balance = sprintf("%.2f",$main_balance); while ($line = <file_read>) { @fields = split /,/, $line; chomp(@fields); $date = @fields[0]; $description = @fields[1]; $length_description = length($description); if ($length_description > 40) { $description = substr $description, 0, 40; substr($description,-1) = "~"; } else { $description = @fields[1]; } if (@fields[2]){ $debit = @fields[2]; #$debit_decimal = sprintf("%.2f",$debit); $format_debit = format_value($debit); $main_balance = $main_balance - $debit; #sprintf file_write "%s\n", $l_format_main_balance; $format_main_balance = format_value($main_balance); #$format_main_balance = sprintf("%.2f",$format_main_balance); printf file_write "%-11s %-41s %10s %11s %11s\n", @fields[0], $d +escription, $format_debit, $blank_credit, $format_main_balance; } else { $credit = @fields[3]; #$credit = sprintf("%.2f",$credit); $format_credit = format_value($credit); $main_balance = $main_balance + $credit; $format_main_balance = format_value($main_balance); #$format_main_balance = sprintf("%.2f",$format_main_balance); printf file_write "%-11s %-41s %10s %11s %11s\n", @fields[0], $d +escription, $blank_debit, $format_credit, $format_main_balance; } } } printf file_write "%-11s %-41s %-11s %-11s %-10s\n",$item_date,$item_d +escription,$item_debit,$item_credit,$item_balance; printf file_write "=================================================== +=====================================\n"; runScript(); close(file_read); close(file_write); exit;
    Text file
    2017-05-01,starting balance to track character count,,900000.00 2017-05-01,phone bill dsfsdfsfdsfsfsfsdfsfsfsfsfdfsdfsfsfsfsf,300000.0 +0, 2017-05-03,Water,100000.34, 2017-05-05,Electric Bill,900.21, 2017-06-03,debit 45678901dfsf2345678901234567890ddddddddddddd,30.32 2017-06-03,12345678901234567890123456789034,,30.98 2017-06-03,credit 8901234567890123456789034567890123,,30.98 2017-06-03,credit dfdfd01234567890123456789034567890123,,30.98 2017-06-08,Food,23.00, 2017-06-12,Cash,20.00,
Escaping double quotes in complete document
5 direct replies — Read more / Contribute
by MeinName
on Jun 26, 2017 at 08:03

    Namaste, dear Perl Monks and Nuns!

    I have a little site to administrate that depends on Perl scripts printing HTML and JavaScript. The site stores data in and loads data from a database using SOAP::Lite and up until last week everything ran very smoothly. Unfortunately our servers got an update that raised Perl from version 5.10.1 to 5.16.3 and there the problems started. Firstly all special characters, like , , , and got mangled by the encoding. This error was resolved by using

    use open qw(:std :utf8); use Encode; use utf8;

    to load the data, by writing

    print header(-type=>'text/html',-charset=>'utf-8'); print start_html(-title => "FooBar");

    to start the web page and by using

    my $text=decode("utf8", $query->param("textbox"));

    to get the data back from the page and store it in the DB.

    Today I had to realize that it's also no longer possible to load strings from the database that contain double quotes, because the HTML textboxes see the double quote as an end marker for the textbox value. (EDIT: Saving content with double quotes is possible. I verified this directly on database level.)

    There are probably even a few more characters that cause issues that I haven't stumbled upon yet.

    I found that I can resolve the issue by using HTML::Entities and calling encode_entities() on the variable I want to see in my textbox, but I am loading hundreds of variables and several arrays of strings in one page visit and there is no way I can revisit every single script in my application to see which variables I maybe need to encode.

    Is there any way I can encode the whole HTML part of my script or a way to circumvent this mess?

    Thanks alot in advance

Add your question
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!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • 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
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            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.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others taking refuge in the Monastery: (6)
    As of 2017-06-29 07:45 GMT
    Find Nodes?
      Voting Booth?
      How many monitors do you use while coding?

      Results (655 votes). Check out past polls.