How to take two input streams?

P

Peng Yu

diff can take two input streams in the following example (if my
interpretation is correct).

diff <(gunzip <a.gz) <(gunzip b.gz)

I'm wondering how to take two streams in a perl program.
 
A

Alan Curry

diff can take two input streams in the following example (if my
interpretation is correct).

diff *requires* two input streams. With only one, it's hard to figure what it
would do.
diff <(gunzip <a.gz) <(gunzip b.gz)

I'm wondering how to take two streams in a perl program.

The <(cmd) syntax is handled by your shell, which substitutes a filename
which may be opened to gain access to the stream. diff doesn't know anything
abou it. diff just finds 2 filenames in argv, opens them, and reads them. You
can do the same in any language, including perl.
 
M

Martijn Lievaart

diff can take two input streams in the following example (if my
interpretation is correct).

diff <(gunzip <a.gz) <(gunzip b.gz)

I'm wondering how to take two streams in a perl program.

This has nothing to do with diff or with perl, it's a function of your
shell. So it works the same for diff as for perl.

HTH,
M4
 
P

Peng Yu

This has nothing to do with diff or with perl, it's a function of your
shell. So it works the same for diff as for perl.

I don't quite understand how this works. Would you please write a
small perl program which can print the two streams (with the following
command) to help me understand it?

example.pl <(cat a.txt) <(cat b.txt)
 
P

Peng Yu

This has nothing to do with diff or with perl, it's a function of your
shell. So it works the same for diff as for perl.

I think that I understand what you mean. <(cmd) is just like a
filename, right?

$ cat main.pl
#!/usr/bin/env perl

use warnings;

open(IN1, $ARGV[0]);
open(IN2, $ARGV[1]);

while(<IN1>) {
print
}

print "------\n";

while(<IN2>) {
print
}

$ ./main.pl <(cat main.pl) <(cat main.pl)
#!/usr/bin/env perl

use warnings;

open(IN1, $ARGV[0]);
open(IN2, $ARGV[1]);

while(<IN1>) {
print
}

print "------\n";

while(<IN2>) {
print
}

------
#!/usr/bin/env perl

use warnings;

open(IN1, $ARGV[0]);
open(IN2, $ARGV[1]);

while(<IN1>) {
print
}

print "------\n";

while(<IN2>) {
print
}
 
P

Peter Makholm

Peng Yu said:
I don't quite understand how this works. Would you please write a
small perl program which can print the two streams (with the following
command) to help me understand it?

example.pl <(cat a.txt) <(cat b.txt)

makholm@makholm:/tmp$ perl ./example.pl <(cat example.pl) <(tr 'a-zA-Z' 'n-za-mN-ZA-M' < example.pl)
001: #!/usr/bin/perl
001:
001: use strict;
001: use warnings;
001:
001: my $fileno;
001: for my $file (@ARGV) {
001: $fileno++;
001: open my $fh, "<", $file
001: or next;
001:
001: printf "%03d: %s", $fileno, $_ while <$fh>;
001: }
001:
001: __END__
002: #!/hfe/ova/crey
002:
002: hfr fgevpg;
002: hfr jneavatf;
002:
002: zl $svyrab;
002: sbe zl $svyr (@NETI) {
002: $svyrab++;
002: bcra zl $su, "<", $svyr
002: be arkg;
002:
002: cevags "%03q: %f", $svyrab, $_ juvyr <$su>;
002: }
002:
002: __RAQ__
makholm@makholm:/tmp$

//Makholm
 
J

John Bokma

Peng Yu said:
$ cat main.pl
#!/usr/bin/env perl

Also add this one:

use strict;
use warnings;
open(IN1, $ARGV[0]);


Use the 3 argument version of open, and it's often a very good idea to
report if the file actually couldn't be opened for reading:

open my $fh, '<', $ARGV[0]
or die "Can't open '$ARGV[0]' for reading: $!";
^--- explains why
 
M

Martijn Lievaart

I think that I understand what you mean. <(cmd) is just like a filename,
right?

It actually gets passed to your program as a filename, although it really
is a pipe to the command between the brackets.

[martijn@cow t]$ perl -e 'print "@ARGV\n"' <(cat t.pl) <(cat t.pl~)
/proc/self/fd/63 /proc/self/fd/62
[martijn@cow t]$

HTH,
M4
 
C

C.DeRykus

....

#!/usr/bin/env perl

use warnings;

open(IN1, $ARGV[0]);
open(IN2, $ARGV[1]);

while(<IN1>) {
  print

}

print "------\n";

while(<IN2>) {
  print

}

Perl provides a handy command line shortcut
if that's all you need (perldoc perlrun):


perl -pwe 'print "------\n" if eof' file1 file2 ...
 
C

chad

I think that I understand what you mean. <(cmd) is just like a filename,
right?

It actually gets passed to your program as a filename, although it really
is a pipe to the command between the brackets.

[martijn@cow t]$ perl -e 'print "@ARGV\n"' <(cat t.pl) <(cat t.pl~)
/proc/self/fd/63 /proc/self/fd/62
[martijn@cow t]$

Why do you use the brackets in '<(cmd)'? Ie, why can't you just do
something like '<cmd' ?
 
R

RedGrittyBrick

On Mon, 31 May 2010 20:47:22 -0700, Peng Yu wrote:
diff can take two input streams in the following example (if my
interpretation is correct).
diff<(gunzip<a.gz)<(gunzip b.gz)
I'm wondering how to take two streams in a perl program.
This has nothing to do with diff or with perl, it's a function of your
shell. So it works the same for diff as for perl.
I think that I understand what you mean.<(cmd) is just like a filename,
right?

It actually gets passed to your program as a filename, although it really
is a pipe to the command between the brackets.

[martijn@cow t]$ perl -e 'print "@ARGV\n"'<(cat t.pl)<(cat t.pl~)
/proc/self/fd/63 /proc/self/fd/62
[martijn@cow t]$

Why do you use the brackets in '<(cmd)'? Ie, why can't you just do
something like '<cmd' ?

Because the shell would look for a data file named 'cmd' in the current
directory and would not execute it as a command.

$ wc -l <ls
-bash: ls: No such file or directory

$ wc -l <(ls)
105 /dev/fd/63
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top