AlexTamayo
AlexTamayo

Reputation: 3

Python - Concatenate a variable into string format

I'm trying to retrieve the number from a file, and determine the padding of it, so I can apply it to the new file name, but with an added number. I'm basically trying to do a file saver sequencer.

Ex.:

fileName_0026

0026 = 4 digits

add 1 to the current number and keep the same amount of digit

The result should be 0027 and on.

What I'm trying to do is retrieve the padding number from the file and use the '%04d'%27 string formatting. I've tried everything I know (my knowledge is very limited), but nothing works. I've looked everywhere to no avail.

What I'm trying to do is something like this:

O=fileName_0026

P=Retrieved padding from original file (4)

CN=retrieve current file number (26)

NN=add 1 to current file number (27)

'%0 P d' % NN

Result=fileName_0027

I hope this is clear enough, I'm having a hard time trying to articulate this.

Thanks in advance for any help.

Cheers!

Upvotes: 0

Views: 385

Answers (5)

PM 2Ring
PM 2Ring

Reputation: 55469

As you can see there are a few ways to do this that are quite similar. But one thing the other answers haven't mention is that it's important to strip off any existing leading zeroes from your file's number string before converting it to int, otherwise it will be interpreted as octal.

edit

I just realised that my previous code crashes if the file number is zero! :embarrassed:

Here's a better version that also copes with a missing file number and names with multiple or no underscores.

#! /usr/bin/env python

def increment_filename(s):
    parts = s.split('_')

    #Handle names without a number after the final underscore
    if not parts[-1].isdigit():
        parts.append('0')

    tail = parts[-1]
    try:
        n = int(tail.lstrip('0'))
    except ValueError:
        #Tail was all zeroes
        n = 0

    parts[-1] = str(n + 1).zfill(len(tail))
    return '_'.join(parts)


def main():
    for s in (
        'fileName_0026',
        'data_042',
        'myfile_7',
        'tricky_99',
        'myfile_0',
        'bad_file',
        'worse_file_',
        '_lead_ing_under_score',
        'nounderscore',
    ):
        print "'%s' -> '%s'" % (s, increment_filename(s))    

    if __name__ == "__main__":
        main()

output

'fileName_0026' -> 'fileName_0027'
'data_042' -> 'data_043'
'myfile_7' -> 'myfile_8'
'tricky_99' -> 'tricky_100'
'myfile_0' -> 'myfile_1'
'bad_file' -> 'bad_file_1'
'worse_file_' -> 'worse_file__1'
'_lead_ing_under_score' -> '_lead_ing_under_score_1'
'nounderscore' -> 'nounderscore_1'

Some additional refinements possible:

  1. An optional arg to specify the number to add to the current file number,
  2. An optional arg to specify the minimum width of the file number string,
  3. Improved handling of names with weird number / position of underscores.

Upvotes: 0

Ian Price
Ian Price

Reputation: 7616

There's a few things going on here, so here's my approach and a few comments.

def get_next_filename(existing_filename):  

    prefix = existing_filename.split("_")[0] # get string prior to _
    int_string = existing_filename.split("_")[-1].split(".")[0] # pull out the number as a string so we can extract an integer value as well as the number of characters
    try:
        extension = existing_filename.split("_")[-1].split(".")[-1] # check for extension
    except:
        extension = None
    int_current = int(int_string) # integer value of current filename
    int_new = int(int_string) + 1 # integer value of new filename
    digits = len(int_string) # number of characters/padding in name
    formatter = "%0"+str(digits)+"d" # creates a statement that int_string_new can use to create a number as a string with leading zeros
    int_string_new = formatter % (int_new,) # applies that format
    new_filename = prefix+"_"+int_string_new # put it all together
    if extension: # add the extension if present in original name
        new_filename += "."+extension
    return new_filename

# since we only want to do this when the file already exists, check if it exists and execute function if so

our_filename = 'file_0026.txt'
while os.path.isfile(our_filename):
    our_filename = get_next_filename(our_filename) # loop until a unique filename found

Upvotes: 1

user3556757
user3556757

Reputation: 3609

import re
m = re.search(r".*_(0*)(\d*)", "filenName_00023")
print m.groups()
print("fileName_{0:04d}".format(int(m.groups()[1])+1))

{0:04d} means pad out to four digits wide with leading zeros.

Upvotes: 0

srj
srj

Reputation: 10121

Use the rjust function from string

O=fileName_0026

P=Retrieved padding from original file (4)

CN=retrieve current file number (26)

NN=add 1 to current file number (27)

new_padding = str(NN).rjust(P, '0')

Result=fileName_ + new_padding

Upvotes: 0

user3378649
user3378649

Reputation: 5354

I am writing some hints to acheive that. It's unclear what exactly you wanna achieve?

fh = open("fileName_0026.txt","r") #Read a file
t= fh.read() #Read the content

name= t.split("_|.") #Output:: [fileName,0026,txt] 
n=str(int(name[1])+1) #27
s= n.zfill(2) #0027

newName= "_".join([fileName,s])+".txt"  #"fileName_0027.txt"
fh = open(newName,"w") #Write a new file*emphasized text*

Upvotes: 0

Related Questions