Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Renaming Multiple Files with Different Names

by Feral_Akodon (Initiate)
on Nov 01, 2011 at 21:49 UTC ( #935231=perlquestion: print w/replies, xml ) Need Help??
Feral_Akodon has asked for the wisdom of the Perl Monks concerning the following question:

I split a tab-delimited file into multiple files based on the value in column one. I modified another person's code and can't figure out how to give the output files custom names. Now I'm trying to rename the files (which all have different names) based on the contents of a tab-delimited text file (again all of the new names are unique).

I know the code to do a single rename but I have been unable to get the correct syntax to rename all files based on the contents of the txt document. I have 736 output files and will likely have to do this in the future with different files, so while I could rename one at a time, it seems like I'm better off in the longrun if I can rename all of the output files using the txt file.

I could also fix the problem with the original split script if I could customize the output names (I could get rid of the intermediate rename script all together). In the program I can modify the output names, but if I change one part of the name (%03d), then I get errors about the file not being clobbered.

Here is the split script.

# config: my $field = 0; my $sep = "\t"; $, = $sep; $\ = $/; my %file; # { ID, sequence, $fh } my $fID = 1; while (<INFILE>) { chomp; my @c = split /$sep/o; my( $key, $ID ) = defined $c[$field] ? ( $c[$field], $fID++ ) : ( '(column not present)', 0 ); unless ( $file{$key} ) { $file{$key}{ID} = $ID; $file{$key}{sequence} = sprintf '%03d.tabular', $file{$key}{ID +}; -f $file{$key}{sequence} and die "Sorry, '$file{$key}{ID}' exists; won't clobber."; open $file{$key}{fh}, ">", $file{$key}{sequence} or die "Error opening '$file{$key}{sequence}' for write - $!"; } print {$file{$key}{fh}} @c; } print OUTFILE $file{$_}{sequence}, $_ for sort { $file{$a}{ID} <=> $file{$b}{ID} } keys %file;

Replies are listed 'Best First'.
Re: Renaming Multiple Files with Different Names
by NetWallah (Abbot) on Nov 02, 2011 at 02:30 UTC
    Monks here can help you, if your are clearer on what you are trying to do.
    We need more specifics - from the program you posted, we see it generates file names like "nnn.tabular".
    What are you trying to change the name to ?

    What did you change "%03d" to ?
    What does your "specification" file look like ?
    Show us the code you used to change a single file name.

                "XML is like violence: if it doesn't solve your problem, use more."

      I would like to change the file names to the value of column one from the original file.

      So I've tried changing %03d to $ID and to $_ (I had no reason to choose this, but just wanted to see if it failed).

      For the single file name, I'm just doing it in command line so as an example

      rename 001.tabular 3972

      I'm not sure what file you mean as the spec file.

        I do have a text file that matches the name of the current file (i.e. old file name) and the new file name. It's in tabular format.

        I feel like it should be a rename code with $ARGV[0] as $old and $ARGV1 as $new. But when I do that it just tries to rename the text file containing the corresponding names.

        Also I'm using Strawberry Perl on a PC, so sometimes it doesn't like command line prompts.

Re: Renaming Multiple Files with Different Names
by graff (Chancellor) on Nov 02, 2011 at 07:22 UTC
    I couldn't understand how your code relates to your description, except for this part:

    if I change one part of the name (%03d), then I get errors about the file not being clobbered.

    That would be happening because you are trying to open file names for output when the files already exist in your current working directory -- your posted code specifically dies when this is the case. You could just create a new directory and run the script there (with adjustments to the input file name).

    For all your concerns about renaming files, I'm wondering why you don't show any use of the rename function. If you have hundreds of files to rename, you just need a list of the existing file names, and a corresponding list of the intended file names (or a method for deriving intended names from existing names, e.g. by adding and/or replacing something). Then just loop over the list:

    for my $old ( @existing_names ) { my $new = $old . ".foobar"; rename $old, $new or warn "rename failed for $old -> $new\n"; }

      I am just using the rename function in command line.

      rename 001.tabular 3972

      As I read your code, it is renaming the files by simply adding the extension of .foobar to each one. I need to completely rename them, so I need to designate $old as $ARGV[0] and $new as $ARGV1 from a text file but it needs to be the column and not the element of the array.

      Even when the file doesn't exist, if I change the "%03d" it still says won't clobber. If I can fix that code to rename the files as the value of column 1 that I am sorting on, I don't have to worry about the renaming code. But when I make changes to the code, I either get won't clobber or still get the exact same names as before (that have no meaning and need to be changed).

        This may achieve what you are trying to do. Your first column is "$key". If you want the files generated to use this, Just replace the corresponding line with:
        $file{$key}{sequence} = $key; # Old stuff was : sprintf '%03d +.tabular', $file{$key}{ID};

                    "XML is like violence: if it doesn't solve your problem, use more."

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://935231]
Approved by philipbailey
and one hand claps...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2017-05-28 22:27 GMT
Find Nodes?
    Voting Booth?