Copying files and changing their names

Discussion in 'Ruby' started by SamF, Mar 14, 2007.

  1. SamF

    SamF Guest

    Hi all,

    I have a directory with numerous folders, each of which contains
    numerous folders and/or files.

    Each of the files in each of these folders has a number. I want to
    iterate through all these files, and, for every file that ends in a
    '[filename]-9', I want to COPY the file and rename it
    '[filename]-final'.

    Is there a simple way to do this in Ruby?

    Any help much appreciated!
    Sam

    --
    Posted via http://www.ruby-forum.com/.
     
    SamF, Mar 14, 2007
    #1
    1. Advertising

  2. Alle mercoled=C3=AC 14 marzo 2007, SamF ha scritto:
    > Hi all,
    >
    > I have a directory with numerous folders, each of which contains
    > numerous folders and/or files.
    >
    > Each of the files in each of these folders has a number. I want to
    > iterate through all these files, and, for every file that ends in a
    > '[filename]-9', I want to COPY the file and rename it
    > '[filename]-final'.
    >
    > Is there a simple way to do this in Ruby?
    >
    > Any help much appreciated!
    > Sam


    NOT TESTED - make a trial with some useless directory before using it on re=
    al=20
    data

    require 'find'
    require 'fileutils'

    =46ind.find('.') do |f|
    FileUtils.cp(f,f.sub(/-9$/, '-final')) if File.file?(f) and f.match /-9$/)
    end

    =46ind.find calls the block passing the name of each file or directory it=20
    contains, recursively. In the block, we use the FileUtils.cp method to copy=
    f=20
    to the file whose name is obtained by rmoving the final -9 and adding -fina=
    l,=20
    but only if the name is the name of a file (not of a directory) and if the=
    =20
    name ends with -9.

    I hope this helps

    Stefano
     
    Stefano Crocco, Mar 14, 2007
    #2
    1. Advertising

  3. SamF

    Sam Fent Guest

    Stefano Crocco wrote:
    >
    > NOT TESTED - make a trial with some useless directory before using it on
    > real
    > data
    >


    Hi Stefano (anzi, 'ciao!'),

    Thank you very much -- that has helped me tremendously. I have one
    further question though. What if, instead of the number "9", I wanted to
    copy the file with the HIGHEST number.

    For example, my files might be

    example1.txt
    example2.txt
    test1.txt
    test2.txt
    test3.txt

    If I wanted to change example2.txt to example-final.txt, and test3.txt
    to test-final.txt, how could I iterate throught the files to find the
    file with the highest number?

    Grazie mille per qualsiasi aiuto,
    Sam

    --
    Posted via http://www.ruby-forum.com/.
     
    Sam Fent, Mar 14, 2007
    #3
  4. SamF

    Sam Fent Guest

    Sam Fent wrote:

    > If I wanted to change example2.txt to example-final.txt, and test3.txt
    > to test-final.txt, how could I iterate throught the files to find the
    > file with the highest number?


    Ok, so I worked it out myself, as I probably should have from the
    beginning.

    This is almost certainly not the most efficient code, in that it
    iterates over the same directories several times, but here it is, in
    case any future person wants to do the same thing (or any present person
    wants to make it more efficient).

    require 'find'
    require 'fileutils'

    usedNames = []

    Find.find('.') do |f|
    if (File.file?(f) and f.match(/txt$/))
    name = f[/.*V/][0..-2]
    if (!usedNames.include?(name))
    usedNames += [name]
    versions = []

    # find the latest version number
    Find.find('.') do |f|
    if (File.file?(f) and f.match(/#{name}.*txt$/))
    versionNumber = f[name.length+1..-5]
    versions += [versionNumber]
    end
    end
    versions = versions.sort
    lastVersionNumber = versions[versions.length-1]

    # copy file and re-name it FINAL
    if (!lastVersionNumber.match(/.*FINAL.*/))
    Find.find(name+"V"+lastVersionNumber+".txt") do |g|
    puts "Changing file " + g + " to: " +
    g.sub(/#{lastVersionNumber}/,"_FINAL")
    FileUtils.cp(g,g.sub(/#{lastVersionNumber}/,"FINAL"))

    end
    end
    end
    end
    end


    --
    Posted via http://www.ruby-forum.com/.
     
    Sam Fent, Mar 14, 2007
    #4
  5. Alle mercoled=C3=AC 14 marzo 2007, Sam Fent ha scritto:
    > Stefano Crocco wrote:
    > > NOT TESTED - make a trial with some useless directory before using it on
    > > real
    > > data

    >
    > Hi Stefano (anzi, 'ciao!'),
    >
    > Thank you very much -- that has helped me tremendously. I have one
    > further question though. What if, instead of the number "9", I wanted to
    > copy the file with the HIGHEST number.
    >
    > For example, my files might be
    >
    > example1.txt
    > example2.txt
    > test1.txt
    > test2.txt
    > test3.txt
    >
    > If I wanted to change example2.txt to example-final.txt, and test3.txt
    > to test-final.txt, how could I iterate throught the files to find the
    > file with the highest number?
    >
    > Grazie mille per qualsiasi aiuto,
    > Sam


    This should work:

    require 'find'
    require 'set'
    require 'file_utils'

    =46ind.find('.') do |f|
    # consider only directories, we'll take care of files later=09
    if File.directory?(f)
    # create a Set containing the names of the files in the directory f [1]
    entries=3DSet.new(Dir.entries(f).reject{|e| File.directory?(e)})
    #separate the files basing on their basename (the part before -number) =
    [2]
    names=3Dentries.classify{|e| e.match(/^.*-\d+$/)[1]}
    # for each of the basenames
    names.each_value do |v|
    # sort the set basing on the number and select the last
    name=3Dv.sort_by{|n| n.match(/-(\d+)/)[1].to_i}.last
    # copy it to the new name. name is relative to f, so we prepend it
    FileUtils.cp "#{f}#{name}", "#{f}#{name.sub(/-\d+$/, '-final')}"
    end
    end
    end

    The line marked by [2] creates a hash of sets, each of them containing the=
    =20
    files with the same basename. This method is the only reason to use a set i=
    n=20
    line [1], instead of keeping the array. For instance, if the directory f=20
    contains the files
    a-1
    a-2
    a-3
    b-1
    b-2
    c-1
    c-2
    c-3
    c-4

    the result of line [2] will be a hash with keys 'a', 'b' and 'c'. The keys =
    'a'=20
    will contain a set with elements 'a-1', 'a-2', 'a-3', and so on for the oth=
    er=20
    keys.

    Stefano
     
    Stefano Crocco, Mar 14, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ashraf Fouad
    Replies:
    2
    Views:
    557
    Ashraf Fouad
    Jan 8, 2004
  2. Tomas PAJER
    Replies:
    4
    Views:
    156
    Patrice
    Nov 28, 2005
  3. Sfdesigner Sfdesigner
    Replies:
    5
    Views:
    168
    Chris Shea
    Aug 13, 2007
  4. Sandman

    input names with '-' in their names.

    Sandman, Sep 3, 2003, in forum: Javascript
    Replies:
    4
    Views:
    105
    Lasse Reichstein Nielsen
    Sep 4, 2003
  5. Replies:
    17
    Views:
    97
    Rustom Mody
    May 22, 2014
Loading...

Share This Page