Jason Wozniak wrote: >> >> I am trying to put together a search and replace program that I can >> string together with typical unix shell commands like find, and >> grep. However, I can't get past the initial read of the files I >> want to process, using the diamond operator. I lose the first >> argument in the list every time. I put the below code together for >> debugging purposes to figure out what's going on. >> >> while (<>) { >> @files = <STDIN>; >> } >> $count = scalar @files; >> print "There are $count files in the process list!\n"; >> print @files; >> >> >> When I run this with the command: find /u06 -name glog.log.bak* | >> /export/home/jwozniak/fm.pl >> It drops the first file in the list for output. >> [snip demonstration] >> >> What am I missing?
You've written: do {@files = <STDIN>} while <>; which looks like you're expecting <> to be some indicator of whether STDIN is empty or not. In fact it's a lot more complicated and magical than that. <> reads lines from all of the files specified on the perl command line and executes the body of the loop with $_ set to each line. If there were no command-line arguments (as in your case) it will try to read lines from STDIN. What's happening then is that the <> executes, finds no parameters, and so reads the first line from STDIN and puts it into $_ for you. This is successful, so the body of the loop executes, putting all of the remaining lines into @files and ignoring $_. <> then executes again and finds it is at end of file for STDIN and so the loop exits. > > Well as a followup to my own email.. > > This works where the while loop does not, so at least now I've found > a way to pipe the output of the unix find command into my program :) > I'm still not sure I understand why though... > > chomp(@files = <>); Yes, but you're still using the 'magic' <> operator when you're not really concerned with command line parameters at all. More directly this should be written: chomp (@files = <STDIN>); > I had also tried: > > while (<>) { > @files = $_; > } > > but that had the same problem, so somehow the while loop causes the > first argument to be dropped from the input stream? No. This will leave your array containing just the last of the filenames. As in the first case, <> redirects its input to STDIN because there are no command-line parameters. It then reads one line at a time from STDIN, assigning to @files the one-element list of just that filename. Each line read will replace the previous one in @files, leaving just the last record. This would work: while (<>) { push @files, $_; } because it adds the record to the end of the array each time. I'm not too hot on Unix, but I think your find command is searching directory '/u06' for files matching 'glog.log.bak*'? This can be done directly in Perl, avoiding all that ugly piping. my @files = glob('/u06/glog.log.bak*'); which may be subtly different from what you have done, but I'm sure someone will let me know! Hope this helps. Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]