Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Pipe filenames, then get user confirmation

by cniggeler (Sexton)
on Sep 03, 2014 at 17:51 UTC ( [id://1099446] : perlquestion . print w/replies, xml ) Need Help??

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

Hi, I am new to perlmonks but have found many useful tidbits in the past! I have an issue and would appreciate assistance.

I would like to pipe filenames to a perl script, and then obtain confirmation from the user before acting on each file. The problem is, while I can get the filenames no problem, the script simply blows past the console read! I've tried clearing ARGV, and flushing stdin, but to no avail.

Here's what a sample session would look like from the command prompt:

$ find . -name (*.html) | xargs grep -l foo | ./myscript.pl
Do you wish to modify file1.html? (y/n) n
Do you wish to modify file2.html? (y/n) y
file2.html modified

and in myfile.pl I would have this:

#!/usr/bin/perl @filelist = <>; { local $/; <STDIN> } for (@filelist) { chomp; print "Do you wish to modify $_? (y/n) "; $ans = uc(<STDIN>); print "$_ modified\n" if substr($ans, 0, 1) eq "Y" }

Thanks!

Replies are listed 'Best First'.
Re: Pipe filenames, then get user confirmation
by AppleFritter (Vicar) on Sep 03, 2014 at 18:25 UTC

    Howdy cniggeler, welcome to the Monastery!

    When you pipe data into a script, its STDIN is connected to that pipe, so if you want to read from the console again, you'll have to close and reopen STDIN:

    #!/usr/bin/perl use strict; use warnings; use feature qw/say/; chomp(my @filelist = <STDIN>); close STDIN; open STDIN, "<", "/dev/tty" or die "Cannot reopen STDIN"; foreach(@filelist) { print "Do you wish to modify $_? (y/n) "; my $ans = uc <STDIN>; say "$_ modified" if $ans =~ m/^Y/; }

    (There may well be CPAN modules for this sort of thing, too; I haven't checked.)

      That worked - thanks! I thought one couldn't close/ reopen STDIN; o/w I would have tried...
Re: Pipe filenames, then get user confirmation
by Anonymous Monk on Sep 03, 2014 at 18:18 UTC

    So, you're reading from STDIN, which has been redirected from a file. And once the file is exhausted, you want STDIN to be changed back to the terminal/keyboard?

    That sounds to me like an OS and/or shell issue which I'm not terribly familiar with, but perhaps another monk can help if you provide those details.

      Yes, correct: read filenames from pipe and once that's exhausted, read user input from STDIN. The behavior is the same in both Windows and Linux, at least on the versions I tested.