Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Perl command to copy one file into another file?

Reply
Thread Tools

Perl command to copy one file into another file?

 
 
Bill
Guest
Posts: n/a
 
      09-27-2003
Is there a single Perl command to copy file 1 into file 2 with out going
through the where-with-all of a while loop? Thanks, Bill

Perl command to copy one file into another file?


 
Reply With Quote
 
 
 
 
ko
Guest
Posts: n/a
 
      09-27-2003
Bill wrote:
> Is there a single Perl command to copy file 1 into file 2 with out going
> through the where-with-all of a while loop? Thanks, Bill
>
> Perl command to copy one file into another file?
>
>


The File::Copy module.

use File::Copy;
copy("file1","file2") or die "Copy failed: $!";

'perldoc File::Copy' gives you all the details

HTH - keith

 
Reply With Quote
 
 
 
 
Bill
Guest
Posts: n/a
 
      09-29-2003
while ( <INPUT1> ) {
# print "Reading $ARGV[0]\n";
print OUTPUT $_;
}

The copy statment, copy("file1","file2") or die "Copy failed: $!"; is
supposed to replace the above while statement.

I get this error with the copy statment ...
C:\PERL1\OUTPUT7>bbbb5.pl output5.txt output6.txt output7.txt
Undefined subroutine &main::copy called at C:\PERL1\OUTPUT7\bbbb5.pl line
24.

This is the script code ...

open (INPUT1, "$ARGV[0]") or die "Cannot open $ARGV[0]";
open (OUTPUT, "> $ARGV[2]");

#print "First input file is: $ARGV[0]\n";
#print "Second input file is: $ARGV[1]\n";
#print "The output file is: $ARGV[2]\n\n";

# This half of the code dumps everything in 'file1' to the output 'file3'
# while ( <INPUT1> ) {
# print "Reading $ARGV[0]\n";
# print OUTPUT $_;
# }

File :: COPY;
copy("$ARGV[0]","$ARGV[2]") or die "Copy failed: $!";

# This half of the code compares 'file2' to 'file1' and writes out
# any line that doesn't match to the output 'file3'

open (INPUT1, "$ARGV[1]") or die "Cannot open $ARGV[1]";

while ( <INPUT1> ) {
$match = 0;

$a = $_;
open (INPUT2, "$ARGV[0]") or die "Cannot open $ARGV[0]";
while ( <INPUT2> ) {
$b = $_;
if ($a eq $b) {
$match = 1;
last;
}
}

if ($match == 0) {
print OUTPUT $a;
}
}

"ko" <(E-Mail Removed)> wrote in message
news:bl37di$j2a$(E-Mail Removed)...
> Bill wrote:
> > Is there a single Perl command to copy file 1 into file 2 with out going
> > through the where-with-all of a while loop? Thanks, Bill
> >
> > Perl command to copy one file into another file?
> >
> >

>
> The File::Copy module.
>
> use File::Copy;
> copy("file1","file2") or die "Copy failed: $!";
>
> 'perldoc File::Copy' gives you all the details
>
> HTH - keith
>



 
Reply With Quote
 
ko
Guest
Posts: n/a
 
      09-29-2003
Bill wrote:

> while ( <INPUT1> ) {
> # print "Reading $ARGV[0]\n";
> print OUTPUT $_;
> }
>
> The copy statment, copy("file1","file2") or die "Copy failed: $!"; is
> supposed to replace the above while statement.
>
> I get this error with the copy statment ...
> C:\PERL1\OUTPUT7>bbbb5.pl output5.txt output6.txt output7.txt
> Undefined subroutine &main::copy called at C:\PERL1\OUTPUT7\bbbb5.pl line
> 24.
>
> This is the script code ...
>
> open (INPUT1, "$ARGV[0]") or die "Cannot open $ARGV[0]";
> open (OUTPUT, "> $ARGV[2]");
>
> #print "First input file is: $ARGV[0]\n";
> #print "Second input file is: $ARGV[1]\n";
> #print "The output file is: $ARGV[2]\n\n";
>
> # This half of the code dumps everything in 'file1' to the output 'file3'
> # while ( <INPUT1> ) {
> # print "Reading $ARGV[0]\n";
> # print OUTPUT $_;
> # }
>
> File :: COPY;


When you 'use' a module case matters, and you forgot 'use'. It should be:

use File::Copy;

That's the reason for the 'undefined subroutine...' error message.

> copy("$ARGV[0]","$ARGV[2]") or die "Copy failed: $!";
>
> # This half of the code compares 'file2' to 'file1' and writes out
> # any line that doesn't match to the output 'file3'
>
> open (INPUT1, "$ARGV[1]") or die "Cannot open $ARGV[1]";
>
> while ( <INPUT1> ) {
> $match = 0;
>
> $a = $_;
> open (INPUT2, "$ARGV[0]") or die "Cannot open $ARGV[0]";
> while ( <INPUT2> ) {
> $b = $_;
> if ($a eq $b) {
> $match = 1;
> last;
> }
> }
>
> if ($match == 0) {
> print OUTPUT $a;
> }
> }
>
> "ko" <(E-Mail Removed)> wrote in message
> news:bl37di$j2a$(E-Mail Removed)...
>
>>Bill wrote:
>>
>>>Is there a single Perl command to copy file 1 into file 2 with out going
>>>through the where-with-all of a while loop? Thanks, Bill
>>>
>>>Perl command to copy one file into another file?
>>>
>>>

>>
>>The File::Copy module.
>>
>>use File::Copy;
>>copy("file1","file2") or die "Copy failed: $!";
>>
>>'perldoc File::Copy' gives you all the details
>>
>>HTH - keith
>>


Maybe I misunderstood what you want to do. In your original post you
stated that you want to copy a file without using a while loop. Above,
however. the contents of the files are being compared. If you want to
compare contents you do need a while loop.

File::Copy does a straight copy, nothing else:

#!/usr/bin/perl -w
use strict;

use File::Copy;
die "Usage: SCRIPTNAME file1 file2\n" unless @ARGV == 2;
copy($ARGV[0], $ARGV[1]) or die "Copy failed: $!";

You should also add a check to see that the new file doesn't already
exist (it will clobber an existing file), and pass the files with
absolute paths.

HTH - keith

 
Reply With Quote
 
Michael P. Broida
Guest
Posts: n/a
 
      09-29-2003
Bill wrote:
>
> Is there a single Perl command to copy file 1 into file 2 with out going
> through the where-with-all of a while loop? Thanks, Bill
>
> Perl command to copy one file into another file?


If you know EXACTLY what kind of system it will run on,
(Windows, Linux, etc) you can use whatever command you
would give to a shell or commandprompt.

Use the ` (backtick) command in perl to run the shell
command:

$result = `copy a.txt b.txt`;

$result will contain whatever output the shell returned
(error messages, success message, whatever). Probably
nothing if it was successful.

Note that that method is not necessarily "portable".

Mike
 
Reply With Quote
 
Bill
Guest
Posts: n/a
 
      09-30-2003
The objective is to create a sum of the two files with out any duplications.
I included "use" into the script, but all it does now is make the file copy
and loops with out making any comapisons with output6.txt.

# To use this script, type the following at the command line prompt:
# bbb.pl file1 file2 output_file_name

open (INPUT1, "$ARGV[0]") or die "Cannot open $ARGV[0]";
open (OUTPUT, "> $ARGV[2]");

#print "First input file is: $ARGV[0]\n";
#print "Second input file is: $ARGV[1]\n";
#print "The output file is: $ARGV[2]\n\n";

# This half of the code dumps everything in 'file1' to the output 'file3'

#while ( <INPUT1> ) {
# print "Reading $ARGV[0]\n";
# print OUTPUT $_;
#}

use File::Copy;
copy("$ARGV[0]","$ARGV[2]") or die "Copy failed: $!";

# This half of the code compares 'file2' to 'file1' and writes out
# any line that doesn't match to the output 'file3'

open (INPUT1, "$ARGV[1]") or die "Cannot open $ARGV[1]";

while ( <INPUT1> ) {
$match = 0;

$a = $_;
open (INPUT2, "$ARGV[0]") or die "Cannot open $ARGV[0]";
while ( <INPUT2> ) {
$b = $_;
if ($a eq $b) {
$match = 1;
last;
}
}

if ($match == 0) {
print OUTPUT $a;
}
}

This is the dir from the command prompt. The script has been running all
night and the output file, output7.txt, is still only as big as the file it
copied yesterday, output5.txt. Output7.txt, the output file should be
growing as comparisons are made with output6.txt.

Directory of C:\PERL1\OUTPUT7

09/29/2003 02:12p <DIR> .
09/29/2003 02:12p <DIR> ..
09/19/2003 10:28p 951 bbbb4.pl
09/30/2003 01:47a 1,291 bbbb5.pl
09/20/2003 07:50p <DIR> Output5
09/20/2003 05:28p 3,965,417 output5.txt
09/20/2003 02:37a <DIR> Output6
09/20/2003 01:24p 3,775,496 output6.txt
09/20/2003 05:28p 3,965,417 output7.txt
5 File(s) 11,708,572 bytes
4 Dir(s) 102,161,915,904 bytes free

C:\PERL1\OUTPUT7>


"ko" <(E-Mail Removed)> wrote in message
news:blag3m$qmr$(E-Mail Removed)...
> Bill wrote:
>
> > while ( <INPUT1> ) {
> > # print "Reading $ARGV[0]\n";
> > print OUTPUT $_;
> > }
> >
> > The copy statment, copy("file1","file2") or die "Copy failed: $!"; is
> > supposed to replace the above while statement.
> >
> > I get this error with the copy statment ...
> > C:\PERL1\OUTPUT7>bbbb5.pl output5.txt output6.txt output7.txt
> > Undefined subroutine &main::copy called at C:\PERL1\OUTPUT7\bbbb5.pl

line
> > 24.
> >
> > This is the script code ...
> >
> > open (INPUT1, "$ARGV[0]") or die "Cannot open $ARGV[0]";
> > open (OUTPUT, "> $ARGV[2]");
> >
> > #print "First input file is: $ARGV[0]\n";
> > #print "Second input file is: $ARGV[1]\n";
> > #print "The output file is: $ARGV[2]\n\n";
> >
> > # This half of the code dumps everything in 'file1' to the output

'file3'
> > # while ( <INPUT1> ) {
> > # print "Reading $ARGV[0]\n";
> > # print OUTPUT $_;
> > # }
> >
> > File :: COPY;

>
> When you 'use' a module case matters, and you forgot 'use'. It should be:
>
> use File::Copy;
>
> That's the reason for the 'undefined subroutine...' error message.
>
> > copy("$ARGV[0]","$ARGV[2]") or die "Copy failed: $!";
> >
> > # This half of the code compares 'file2' to 'file1' and writes out
> > # any line that doesn't match to the output 'file3'
> >
> > open (INPUT1, "$ARGV[1]") or die "Cannot open $ARGV[1]";
> >
> > while ( <INPUT1> ) {
> > $match = 0;
> >
> > $a = $_;
> > open (INPUT2, "$ARGV[0]") or die "Cannot open $ARGV[0]";
> > while ( <INPUT2> ) {
> > $b = $_;
> > if ($a eq $b) {
> > $match = 1;
> > last;
> > }
> > }
> >
> > if ($match == 0) {
> > print OUTPUT $a;
> > }
> > }
> >
> > "ko" <(E-Mail Removed)> wrote in message
> > news:bl37di$j2a$(E-Mail Removed)...
> >
> >>Bill wrote:
> >>
> >>>Is there a single Perl command to copy file 1 into file 2 with out

going
> >>>through the where-with-all of a while loop? Thanks, Bill
> >>>
> >>>Perl command to copy one file into another file?
> >>>
> >>>
> >>
> >>The File::Copy module.
> >>
> >>use File::Copy;
> >>copy("file1","file2") or die "Copy failed: $!";
> >>
> >>'perldoc File::Copy' gives you all the details
> >>
> >>HTH - keith
> >>

>
> Maybe I misunderstood what you want to do. In your original post you
> stated that you want to copy a file without using a while loop. Above,
> however. the contents of the files are being compared. If you want to
> compare contents you do need a while loop.
>
> File::Copy does a straight copy, nothing else:
>
> #!/usr/bin/perl -w
> use strict;
>
> use File::Copy;
> die "Usage: SCRIPTNAME file1 file2\n" unless @ARGV == 2;
> copy($ARGV[0], $ARGV[1]) or die "Copy failed: $!";
>
> You should also add a check to see that the new file doesn't already
> exist (it will clobber an existing file), and pass the files with
> absolute paths.
>
> HTH - keith
>



 
Reply With Quote
 
Eric Schwartz
Guest
Posts: n/a
 
      09-30-2003
"Bill" <(E-Mail Removed)> writes:
> The objective is to create a sum of the two files with out any duplications.
> I included "use" into the script, but all it does now is make the file copy
> and loops with out making any comapisons with output6.txt.


Here's the problem: we're not psychic. You asked for a solution that
copied one file to another, and you got that. Now you appear to want
to roll your own version of diff(1), instead. We can't help you
unless we know what you actually want-- if you ask for something else,
don't be surprised if you get that instead.

> # To use this script, type the following at the command line prompt:
> # bbb.pl file1 file2 output_file_name
>
> open (INPUT1, "$ARGV[0]") or die "Cannot open $ARGV[0]";


Useless use of quotes, and you didn't use $! in your error string:

open (INPUT1, $ARGV[0]) or die "Cannot open $ARGV[0]: $!";


Also, every Perl program you write should begin with:

#!/path/to/perl # please put the REAL path to perl here!!!
use warnings;
use strict;

> open (OUTPUT, "> $ARGV[2]");


Why didn't you die() on error here, too?

open (OUTPUT, "> $ARGV[2]") or die "Cannot open $ARGV[2]: $!";

Only that's wrong, you don't want to do that here. Wait until after
you've done the copy, and THEN open it for append, not write.

> #print "First input file is: $ARGV[0]\n";
> #print "Second input file is: $ARGV[1]\n";
> #print "The output file is: $ARGV[2]\n\n";
>
> # This half of the code dumps everything in 'file1' to the output 'file3'
>
> #while ( <INPUT1> ) {
> # print "Reading $ARGV[0]\n";
> # print OUTPUT $_;
> #}
>
> use File::Copy;
> copy("$ARGV[0]","$ARGV[2]") or die "Copy failed: $!";


copy($ARGV[0], $ARGV[2]) or die "Copy failed: $!";

There's no need to quote variables by themselves like that. It can
even cause problems in some cases. Stop doing that.

Also, everything that happened before happens now-- i.e., after the
copy() call is through, file3 is an exact copy of file1.

> # This half of the code compares 'file2' to 'file1' and writes out
> # any line that doesn't match to the output 'file3'
>
> open (INPUT1, "$ARGV[1]") or die "Cannot open $ARGV[1]";


open(INPUT1, $ARGV[1] or die "Cannot open $ARGV[1]: $!";

Why are you re-opening INPUT1 here? You're using INPUT2 below, but
you never open it. Are you meaning to do that here?

You also want to open $ARGV[2] for output here:

open(OUTPUT, '>>', $ARGV[2]) or die "couldn't open $ARGV[2] for append: $!";

> while ( <INPUT1> ) {
> $match = 0;
>
> $a = $_;


while(my $a = <INPUT1>) {
$match = 0;

> open (INPUT2, "$ARGV[0]") or die "Cannot open $ARGV[0]";


open (INPUT2, $ARGV[0]) or die "Cannot open $ARGV[0]: $!";

> while ( <INPUT2> ) {
> $b = $_;
> if ($a eq $b) {
> $match = 1;
> last;
> }
> }
>
> if ($match == 0) {
> print OUTPUT $a;
> }


Ick. Try this (untested)

print OUTPUT $a unless grep /^\Q$a\E$/, <INPUT2>;

> }


This is a mess, and I'm fairly sure none of it does either what you
think it does, or what you want it to. First, you read a line from
the second input file. Then you assign it to $a. Remember, INPUT1 is
a filehandle for the contents of $ARGV[1].

Then you read from INPUT2, which you never opened, so naturally
nothing is read. If you'd enabled warnings, perl would have said
something like: "readline() on unopened filehandle INPUT2 at - line
<foo>." Anyway, the logic is completely reversed-- after the copy,
file3 is the same as file1, so you should isntead read file2, and then
print out whatever's in that file that is NOT in file1.

First off, this is a generally horrible solution, as you have to read
through the entire contents of file1 EACH BLOODY TIME, which means
horrid runtimes. A much better solution is to read both files, once,
into a hash, and let that handle uniqueness for you:

#!/usr/bin/perl
use warnings;
use strict;

my $output = pop @ARGV;
my %lines = ();
while(<>) {
chomp;
$lines{$_}++;
}

open(OUTPUT, '>', $output) or die "couldn't open $output: $!";
print OUTPUT join("\n", keys %lines), "\n";

There's probably even better solutions; this is just off the top of my
head.

-=Eric
--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
-- Blair Houghton.
 
Reply With Quote
 
ko
Guest
Posts: n/a
 
      09-30-2003
"Bill" <(E-Mail Removed)> wrote in message news:<P4heb.1765$(E-Mail Removed)>...
> The objective is to create a sum of the two files with out any duplications.
> I included "use" into the script, but all it does now is make the file copy
> and loops with out making any comapisons with output6.txt.
>



[snip]


Ok, I mentioned this already, but File::Copy will *NOT* do what you
are looking for. It copies files, *nothing* else. When you use the
module there is no need to open filehandles, loop through the files,
etc., you simply pass the pathnames to the files. Please read the
documentation...

So forget about File::Find in your code.

One way to accomplish your task is:

1. Build an array for file1 that consists of all lines in file1. Do
the same for the second file - this can be done in one step.

2. Build a hash where the keys are the elements of the arrays created
above

3. Print out the hash keys to the third file.

Basically what you want is a 'union' of the two files. The code is
available in perlfaq4, 'How do I compute the difference of two arrays?
How do I compute the intersection of two arrays?' You can cut and
paste the example code, but you only need the @union array ((@array1
and @array2 will represent the two arrays in step 1).

One last suggestion. Try to be more specific when you post a question.
The original post and this last post are entirely different questions.

HTH - keith
 
Reply With Quote
 
Jay Tilton
Guest
Posts: n/a
 
      09-30-2003
[Please do not top-post replies. Please trim reply-quoted material to
the minimum necessary to establish context. See the clpm posting
guidelines at http://mail.augustmail.com/~tadmc/clpmisc.shtml for
explanations and other good advices.]

"Bill" <(E-Mail Removed)> wrote:

: The objective is to create a sum of the two files with out any duplications.

This problem is a variation on finding the elements in one array that
are not in another, which was discussed very recently in the thread
"Find what is in array1 and not in array2." You might find the
algorithms presented in that thread useful.

: I included "use" into the script, but all it does now is make the file copy
: and loops with out making any comapisons with output6.txt.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^
I doubt that's true. Just because you don't see evidence that it's
happening doesn't mean it's not happening.

: # To use this script, type the following at the command line prompt:
: # bbb.pl file1 file2 output_file_name
:
: open (INPUT1, "$ARGV[0]") or die "Cannot open $ARGV[0]";
^ ^
^ ^
Useless use of quotes.
See perlfaq4, ' What's wrong with always quoting "$vars"? '

: open (OUTPUT, "> $ARGV[2]");

Always check the return from open() for success.

open (OUTPUT, "> $ARGV[2]")
or die "Cannot open $ARGV[2]: $!";

: use File::Copy;
: copy("$ARGV[0]","$ARGV[2]") or die "Copy failed: $!";
^ ^ ^ ^
^ ^ ^ ^ More UUoQ.

Copying over a file while it is open feels like a bad idea. Better to
copy the file first, then open the output file for appending.

[snip rest of code]

: The script has been running all night

Comparing each line in one file with each line in another is going to be
slow--very slow when those files are each 3-meg long. Imagine reading
one 9-terabyte file to get an idea of scale.

: and the output file, output7.txt, is still only as big as the file it
: copied yesterday, output5.txt.

The file's size, as reported by "dir", is not updated until the file is
closed.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
copy the last n-bytes of a big file into another file tirzan C++ 5 04-02-2010 09:55 AM
Problem to insert an XML-element by XSLT-converting from one XML-file into another XML-file jkflens XML 2 05-30-2006 09:41 AM
Pull out only first field of ps command ( in Perl ) PERL RUN COMMAND tweetiebirds@gmail.com Perl Misc 2 03-26-2005 06:03 AM
Need to concatenate all files in a dir together into one file and read the first 225 characters from each file into another file. Tony Perl Misc 5 04-19-2004 03:28 PM
Perl command to copy one file into another Bill Perl Misc 6 09-30-2003 04:59 PM



Advertisments