http://qs321.pair.com?node_id=955376

abcdefg has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use an executable through my perl script which takes an input file and gives an output file with name output_.$inputfile. I want to check if this file output_.$inputfile already exists and if it already exist then add a numerical suffix as that can be incremented for each run. How can I do that.

$abc_cmd = "abc.exe -i $input_file -o output_$input_file ";

Replies are listed 'Best First'.
Re: incrementing the file
by toolic (Bishop) on Feb 21, 2012 at 20:10 UTC
    You could use a file test like -e in a while loop:
    my $output_file = "output_$input_file"; my $i = 1; while (-e $output_file) { $output_file = "output_$input_file$i"; $i++; } $abc_cmd = "abc.exe -i $input_file -o $output_file ";
Re: incrementing the file
by kcott (Archbishop) on Feb 21, 2012 at 20:25 UTC

    There's a large number of file test unary operators which will check files for existence, size, writability and so on.

    It's unclear whether you're renaming an existing file or generating a new, unique filename. If the former, File::Copy may be your best bet (there is a rename function but it has documented limitations).

    -- Ken

      Hi Ken, I am generating a new file which has name of previous file and a numerical suffix which is incremented everytime... eg file 1 then file 2.....

        You can try starting with a "templated" filename and increment it until you get past all the existing files:

        my $fn = "output000"; $fn++ while -e $fn;

        At that point, you'll have a filename that is just past the last one of that pattern. Minor caveat: make sure you have enough zeroes at the end of the template - or you'll start incrementing the characters. Yes, really.

        ben@feynman:~$ perl -wle'$number = "one"; $number++ for 1..3624; print + $number' two

        :)

        -- 
        I hate storms, but calms undermine my spirits.
         -- Bernard Moitessier, "The Long Way"
Re: incrementing the file
by GrandFather (Saint) on Feb 21, 2012 at 20:20 UTC

    What have you tried? You do know about Perl's file test operators such as -f (see perldoc -f -X) don't you?

    True laziness is hard work
Re: incrementing the file
by Marshall (Canon) on Feb 22, 2012 at 07:19 UTC
    This is another approach. Read the file names in the output directory, filter out the ones that aren't really simple files (maybe there is some directory with a similar name), get the revision numbers of those files, get the max revision number and then add one to that.

    #!/usr/bin/perl -w use strict; use List::Util qw(max); # List::Util is a core module # that means you don't have to # install it - its already there. my $output_dir = 'C:/TEMP'; my $program_root_name = "some_prog"; opendir DIR, $output_dir or die "cannot open $output_dir for reading $!"; my @current_numbers = map { /^$program_root_name(\d+)$/ ? $1 : () } # just the numbers grep{ -f "$output_dir/$_"}readdir DIR; # only "real" files # not directories closedir DIR; # purely optional foreach (@current_numbers) #intermediate print routine... { print "$output_dir/$program_root_name$_ exists!\n"; } my $max_cur_number = max(@current_numbers); my $new_max = ++$max_cur_number; print "The next highest number is $new_max\n"; print "Full name of next file in sequence would be: ". "$output_dir/$program_root_name$new_max\n"; __END__ The above prints: Note: I made the dummy files: some_prog1 and some_prog3... C:/TEMP/some_prog1 exists! C:/TEMP/some_prog3 exists! The next highest number is 4 Full name of next file in sequence would be: C:/TEMP/some_prog4
Re: incrementing the file
by lune (Pilgrim) on Feb 22, 2012 at 13:06 UTC

    The problem with your approach is, that you have to check an ever growing number of files to determine the current version. The alternative is of course some kind of bookkeeping.

    The simplest form I could think about is using a "output_$input_file_current" with a symlink to the real file "output_$input_file_$version". That way you only have to get the real file name of the symlink with readlink to determine the current maximum.

      Or create a last.txt, containing the name of the latest file. Your open it at the start of your program, overwrite and close it at the end. Not very elegant, but simple and robust.