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

Copy multiple lines to a loop

by eyekona (Acolyte)
on May 20, 2014 at 16:13 UTC ( #1086814=perlquestion: print w/replies, xml ) Need Help??
eyekona has asked for the wisdom of the Perl Monks concerning the following question:

At the moment I have this code snippet...
#!/usr/bin/perl while(<>) { chomp; s/^\s+//; s/\s+$//; next if /^$/; #Next if empty... #do something with the text copied to this loop... #just to do something as an example... print "$_ \n"; }
It's working fine and is doing what I want it to do - with one little exception... If I copy not just one line but multiple lines to the loop, it just prints the first of this lines. If i want it to print more of this lines I have to press enter repeatedly till it is done... if I copy or write anything to he loop until the lines are all done it mixes them up... But I want it to be able to process more then one line at a time - example: What it does:
#1st Example a #input (a) a #output #2nd Example a #input (a newline b pasted to the loop) ba #input and output #press enter b #output #3rd Example a #input (a newline b pasted to the loop) ba #input and output c #input (c) bc #output and output
What I want it to do:
a #input a #output a #input (a newline b pasted to the loop) b #continuing a #output b #without pressing enter again
Problem is - I'm not sure what to change because I can't find out why this is happening... Any idea?

Replies are listed 'Best First'.
Re: Copy multiple lines to a loop (echo race)
by tye (Sage) on May 20, 2014 at 17:23 UTC

    Sounds like you are just missing the final newline when you paste. Paste 3 or more lines to verify that.

    There is also a race as to how quickly the output will appear. Well, you wouldn't have this problem on, for example, Windows, as it echos input characters when they are read. Unix echos input characters when they are typed (which is a particularly bad choice when prompting for a password -- but it isn't like Unix is going to change this).

    I see no easy way to work around this (unless switching to Windows happens to be easy in your case :). You could turn off echo but you probably want echo in some cases. You could turn off echo, put the tty in raw mode, and emulate echo. That is a lot of work compared to the code you have right now.

    - tye        

      I will not change to windows but I will ask some of the windows users if it is actually working for them.
        but I will ask some of the windows users if it is actually working for them

        That would require "the windows users" to be running the script on Windows. But elsewhere you said:

        But as several other people use this script some are also connecting to this linux server from windows and mac clients

        That won't make a difference as the ssh client will be reading what they paste asynchronously and thus (on Windows) causing it to be echoed before the script has read that same data.

        - tye        

Re: Copy multiple lines to a loop
by zentara (Archbishop) on May 20, 2014 at 17:25 UTC
    Here is a little Glib event-loop hack that will copy a multiline input, but you must end your input with a Control-d.
    #!/usr/bin/perl -w use strict; use Glib qw(TRUE FALSE); $|++; print "Enter multi-lines, and finish with Control-d\n"; my $main_loop = Glib::MainLoop->new; #my $watcher; #$watcher = Glib::IO->add_watch( fileno( $pty ), ['in', 'hup'], \&call +back); Glib::IO->add_watch (fileno 'STDIN', [qw/in/], \&watch_callback, 'STDI +N'); $main_loop->run; sub watch_callback { # print "@_\n"; my ($fd, $condition, $fh) = @_; my (@lines) = (<STDIN>); print @lines; #always return TRUE to continue the callback return TRUE; }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Copy multiple lines to a loop
by hippo (Monsignor) on May 20, 2014 at 17:00 UTC

    Standard input from your terminal is line-buffered so your loop will process each line as it arrives.

    To see the output you have shown you could either disable the line-buffering of STDIN (I've never done that and with pretty good reasons) or disable line-buffering of STDOUT (less problematic) or else save your output in the loop to a variable rather than printing directly and then print the entire variable on loop exit.

    In any of these cases you will need to send the EOT character to notify the script of the end of input. This is typically ^D

      Use a variable... Yes sometimes I'm an idiot. Stuff like this happens when admins try to be programmers...
Re: Copy multiple lines to a loop
by RonW (Priest) on May 20, 2014 at 17:24 UTC

    What is your environment? Windows, Linux, Mac, other? what version of Perl?

    I think this is not a Perl problem, rather your command line "terminal emulation".

    If you can paste the lines in to a file, save the file, then perl file.txt and it works as you expect, then it has something to do with how your command line environment handles input (and output).

    Often, the command line terminal emulation treats a pasted "line terminator" differently than a press of the "Enter" key on your keyboard. you might be able to work around this some of the problems by changing the value of $/, but doing so might cause other problems because this is taken as the literal line separator, not as a regular expression.

      Script is running on an console-only linux server, I ssh to from my also linux client. But as several other people use this script some are also connecting to this linux server from windows and mac clients... I did not write this script and just got the quest to make it process multiple lines...

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1086814]
Approved by davido
[Lady_Aleena]: Renaming things like get_THAC0 to just THAC0 was easy. These are harder.
[james28909]: consolidate the three subs into one
[Lady_Aleena]: Um, what?
[james28909]: check is is data or hash or array and do tasks then return needed data
[Lady_Aleena]: james28909, you might want to look at the other two on my scratchpad.
[james28909]: after you send to a sub, you can check if it is array or ref ect with ref
[james28909]: check if it is a hash or an array ect with ref in one sub.

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (8)
As of 2017-05-24 04:52 GMT
Find Nodes?
    Voting Booth?