Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Please help me with this:

Status
Not open for further replies.

SkyHigh

Technical User
May 30, 2002
309
0
0
CA
Hi Folks

I have about 500 text files, what I need to do using a perl script is to rename these file names with the text in the first line of each file.

Thanks for your help in advance.

Rgds
Brenda
 
Try this

- open the file
- read the first line
- close the file
- rename the file

You can do all this in a loop.

Does this help?

tgus

____________________________
Families can be together forever...
 
Hi tgus

Thanks for your reply can you please do me a favour by writing it in perl code

Your help would be much appreciated.

Thanks
Brenda
 
keep all the 500 file names(path) in a single file one per line.
pass the filename containing the 500 filenames as an argument to the perl script file
take the file name into a file handle
pass the file handle into an array
with the help of foreach loop open each file
read the first line and pass into another variable
close the file
rename the file with the variable.
 
Hi 1surya

Thanks for your response, if you can give me the code it will be much appreciated.

Thanks
Brenda
 
Brenda,

I'm sorry I took a while. I wanted to test it first. And then work got in the way.

You'll want to change the name of the directory. But this should do it for you.

my $dir = "c:/temp/tmp";
opendir (DIR, $dir) || die "Shucks $!";
@files = readdir (DIR);
closedir (DIR);

foreach $file (@files){
next if($file =~ /^\./); # skip if it's the '.' or '..' directories
open (FILE, &quot;<$dir/$file&quot;) || die &quot;Shucks $!&quot;;
@rnm = <FILE>;
close(FILE);
rename &quot;$dir/$file&quot;,&quot;$dir/@rnm[0]&quot;;
}

I'm sure someone else can show you a better, cleaner (lazier) way. And I'm looking forward to seeing what it is.

1surya,
I like your idea too. But how do you get the names in the list to correlate with the actual filenames? Or did I miss something?

HTH tgus

____________________________
Families can be together forever...
 
Hi,

You can even try this.

foreach $file (@files)
{
if(! -d $file)
{
open (NEWNAME, &quot;head -1 $file&quot;) || die &quot;Cannot open $file:$!&quot;;
@rnm = <NEWNAME>;
close(NEWNAME);
rename &quot;$dir/$file&quot;,&quot;$dir/$rnm[0]&quot;;
}
}
 
You can do
Code:
$rnm = <FILE>;
to pick off the first line. then you don't spend time and resources reading the entire file into an array.

(vgg: i you have to pipe the output of the head command to get that to work. [tt]&quot;head -1 $file|&quot;[/tt])

jaa
 
Oops!!
I left that out.Thanks for the correction justice.

VGG
 
Thanks so much guys !!!

I tried the following and it does not seem to do anything, and throws no error either :

#!/usr/bin/perl -w

$base_dir = $ARGV[0];

if ( scalar(@ARGV) < 1 )
{
die &quot;Usage: $0 base_dir \n&quot;;
}

opendir(DIR, $base_dir) || die &quot;can't opendir $base_dir: $!&quot;;

@file = readdir(DIR);

foreach $file (@files){
next if($file =~ /^\./); # skip if it's the '.' or '..' directories
open (FILE, &quot;<$dir/$file&quot;) || die &quot;Shucks $!&quot;;
@rnm = <FILE>;
close(FILE);
rename &quot;$dir/$file&quot;,&quot;$dir/@rnm[0]&quot;;
}
 
You read the directory into an array called &quot;@file&quot;, yet your foreach steps over an array called &quot;@files&quot;.

If this is how your code actually is, that's the problem.
 
Nice catch, i skipped right over that. This is the kind of mistake that [tt]use strict;[/tt] would have caught for you.

jaa
 
Oh, I also forgot to mention that you access single array elements with [tt]$array[0][/tt] not [tt]@array[0][/tt]. The later is a slice of a single element, which in this case will give you the same result but don't do it anyway. It can cause unexpected results because it puts things in list context rather than scalar context. So your code should read
Code:
    chomp @rnm; # Important!
    rename &quot;$dir/$file&quot;,&quot;$dir/$rnm[0]&quot;;
or better yet
Code:
    open (FILE, &quot;<$dir/$file&quot;) || die &quot;Shucks $!&quot;;
    my $rnm = <FILE>;
    close(FILE);
    chomp $rnm; # This is important!
    rename &quot;$dir/$file&quot;,&quot;$dir/$rnm&quot;;

jaa
 
I would use
Code:
-d $file
instead of
Code:
$file =~ /^\./
(see vgg post above).

Otherwise, subdirectories other than . and .. will cause your program to die.

And follow justice41 advices !
 
Justice,
Thanks for that fix. I thought about $rnm[0] instead of @rnm[0]
But I'm still not really clear on that stuff. I would have tried $rnm[0] if the other had failed on me in testing, but it worked fine. I also like your use of $rnm instead of @rnm. I didn't know you could do that. How does that work?

dchoulette,
I had assumed (you know what happens when we assume) that she had no other sub directories. Also I've been doing some desting with -d lately and having mixed results, so I didn't want to mislead Brenda. Besides, I had to leave something for someone else to help with.

Brenda,
Is that working for you now?

tgus

____________________________
Families can be together forever...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top