2

I have a bunch of files in a directory. They are automatically downloaded with the following names:

new.pdb
new(1).pdb
new(2).pdb and so on

I have a list of the actual filenames like:

AAA
BBB
CCC

I want a way to rename the files with their corresponding names in the list where new.pdb would be AAA.pdb, new(1).pdb would be BBB.pdb and so on. I'd really appreciate if you could give me a hint before you down vote. I've tried well enough to solve this but couldn't. I've tried this so far. But the issue with the following code is that a few files may download faster than the ones that started before them. So it doensn't rename as I wanted.

    infiles = filter(os.path.isfile, os.listdir(os.getcwd()))
    infiles = [os.path.join(os.getcwd(), f) for f in infiles] 
    infiles.sort(key=lambda x: os.path.getmtime(x))
    last_file = infiles[-1]
    if rename_files.endswith(".pdb"):
        os.rename(last_file, directory_name+".pdb")
2
  • You have last_file = infiles[-1] then you try to loop over that single path with for rename_files in last_file: I think this is not doing what you describe in the text of your question. Commented Aug 21, 2014 at 3:51
  • for loop is something that I tried later to see if it's make any difference. Thanks for the catch! @dawg Commented Aug 21, 2014 at 3:55

1 Answer 1

4

The first three lines are correct.

However, for the for <variable> in <collection> construct to work, the <collection> needs to be a collection. last_file is string, thus a collection of characters; and it is impossible for a single character to end with .pdb.

Assuming rename_files is the list of new names, you want this after your first three lines:

infiles = (infile for infile in infiles if infile.endswith(".pdb"))
for infile, outfile in zip(infiles, rename_files):
    os.rename(infile, outfile + ".pdb")

zip will create a list of pairs from lists, so you first find all pdb files, pair them up with new names, then rename each according to the pair.

EDIT: if you want to go by the file names rather by your original mtime, you'll need to extract that number and sort by it:

def get_rank(infile):
    m = re.search(r'(?:\((\d+)\))[^()]*', infile)
    if m:
        return int(m.group(1))
    return 0 
infiles = filter(os.path.isfile, os.listdir(os.getcwd()))
infiles = [os.path.join(os.getcwd(), f) for f in infiles if f.endswith('.txt')]
filerank = (get_rank(infile) for infile in infiles)
renames = zip(filerank, infiles, rename_files)
renames.sort(key=lambda x: x[0])
for _, infile, outfile in renames:
    os.rename(infile, outfile + ".pdb")
Sign up to request clarification or add additional context in comments.

1 Comment

So it again renames based on the date modified right? Is there any way I can rename based on the file name? Because, for example, file1 started downloading before file2, but is huge and hence finishes after file2, this method considers file2 to be file1 since it finished downloading first. I'm sorry for my clumsy English.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.