#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    5
    Rep Power
    0

    Copy files from source directory to the destination directory


    Hi,
    I want to copy files from source directory to the destination directory but
    1. if the given file is not there in source dir, it should print error message,
    2. if file is already there in destination address, it should print 'file already exists' and rename the old file by 'file.old' and copy the given file.
    But the problem is, this condition 'if os.path.isfile(file):' is always holding True, not going to else part?

    Below is the basic code i am trying:

    Code:
    import glob, os, shutil
    source_dir = '/root/home'
    dest_dir = '/root/home/new'
    filename = 'FILE.txt'
    files = glob.iglob(os.path.join(source_dir, filename))
    for file in files:
            if os.path.isfile(file):
                    files2 = glob.iglob(os.path.join(dest_dir, filename))
                    for file1 in files2:
                            if os.path.isfile(file1):
                                    print ('file already exists')
                            else:
                                    shutil.copy2(file, dest_dir)
            else:
                    print ('File does not exist in given source_dir')
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Location
    Usually Japan when not on contract
    Posts
    240
    Rep Power
    11
    glob is tripping you up here. glob returns a list of found files, and you're then testing to see if they exist 1 for 1. Unless they get deleted between the time glob checks and the time your script checks then your test will always be true.

    What you want to do is split the filename element of the path found by glob off and put it together with the dest_dir and see if that path exists yet or not:
    python Code:
    # This
    if os.path.isfile(os.path.join(dest_dir, os.path.split(file)[1])):
     
    # Not this
    if os.path.isfile(file):

    That said, making "filename" into a list of paths found by glob (or walk, or a combination of the two depending on your needs) and then creating a list of complete paths for source and dest to iterate over might make more sense.
    python Code:
    # Note that seek, source_dir and dest_dir should be an argument or list
    # of arguments for this to be useful...
    import os, shutil, glob
    source_dir = '/root/home'
    dest_dir = '/root/home/new'
    seek = 'FILE.txt'
    paths = [(os.path.join(source_dir, z), os.path.join(dest_dir, z))
             for z in glob.glob(seek)]
    for p in paths:
        if os.path.isfile(p[1]):
            new_path = p[1] + '.bak'
            print ('File "{0}" already exists; moving to "{1}"'.format(p[1], new_path))
            shutil.move(p[1], new_path)
        shutil.copy2(p[0], p[1])

    Blah blah. I didn't test the stuff I wrote above, so there's probably typo or a faulty function call or whatever -- but I think you get the idea. The bottom "else" was completely redundant (so I snipped it off), since glob won't return something that doesn't exist, so you'll never have the situation where your original test would have been false.
    Last edited by zxq9; July 11th, 2013 at 01:44 AM.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    5
    Rep Power
    0
    Originally Posted by zxq9
    glob is tripping you up here. glob returns a list of found files, and you're then testing to see if they exist 1 for 1. Unless they get deleted between the time glob checks and the time your script checks then your test will always be true.

    What you want to do is split the filename element of the path found by glob off and put it together with the dest_dir and see if that path exists yet or not:
    python Code:
    # This
    if os.path.isfile(os.path.join(dest_dir, os.path.split(file)[1])):
     
    # Not this
    if os.path.isfile(file):

    That said, making "filename" into a list of paths found by glob (or walk, or a combination of the two depending on your needs) and then creating a list of complete paths for source and dest to iterate over might make more sense.
    python Code:
    # Note that seek, source_dir and dest_dir should be an argument or list
    # of arguments for this to be useful...
    import os, shutil, glob
    source_dir = '/root/home'
    dest_dir = '/root/home/new'
    seek = 'FILE.txt'
    paths = [(os.path.join(source_dir, z), os.path.join(dest_dir, z))
             for z in glob.glob(seek)]
    for p in paths:
        if os.path.isfile(p[1]):
            new_path = p[1] + '.bak'
            print ('File "{0}" already exists; moving to "{1}"'.format(p[1], new_path))
            shutil.move(p[1], new_path)
        shutil.copy2(p[0], p[1])

    Blah blah. I didn't test the stuff I wrote above, so there's probably typo or a faulty function call or whatever -- but I think you get the idea. The bottom "else" was completely redundant (so I snipped it off), since glob won't return something that doesn't exist, so you'll never have the situation where your original test would have been false.

    Thanks,but it is not going to the loop 'for p in paths:' in any case even the file exists in source_dir :-(
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Location
    Usually Japan when not on contract
    Posts
    240
    Rep Power
    11
    That's because your "source_dir" is probably different from the current directory. So either have the environment cd to it or modify the argument to glob()...

    Don't just cut and paste -- think about what is going on.

    Here is a lesson for you. Compare the vesion below to the one above and tell me why the bottom one works and the top one doesn't:
    python Code:
    import os, shutil, glob
    source_dir = '/path/a'
    dest_dir = '/path/b'
    seek = 'foo.txt'
    paths = [(z, os.path.join(dest_dir, os.path.split(z)[1]))
             for z in glob.glob(os.path.join(source_dir, seek))]
    for p in paths:
        if os.path.isfile(p[1]):
            new_path = p[1] + '.bak'
            print ('File "{0}" already exists; moving to "{1}"'.format(p[1], new_path))
            shutil.move(p[1], new_path)
        shutil.copy2(p[0], p[1])

    Also, don't quote my entire message. We already know what thread we're in -- give my scroll wheel a break.

    And one more thing... I just realized that you're paths start at "/root" ... which means you're experimentally practicing programming from the root account on your machine. I strongly recommend you cut that out before you make yourself cry with a misplaced command. You're practicing file operations for Pete's sake! And you're copy-pasting from a forum! What if I was a meanie and wrote some code above that would Pythonically obliterate your system? Sheesh!
    Last edited by zxq9; July 11th, 2013 at 02:59 AM.

IMN logo majestic logo threadwatch logo seochat tools logo