查找名称中整数最大的文件名

Find filename with highest integer in name

总结

如果 FCR_Network_Coordinates_0 和 FCR_Network_Coordinates_2 存在,它应该写入文件 FCR_Network_Coordinates_3 而不是 FCR_Network_Coordinates_1

详情

我有以下问题:

我想写一个新的 csv 文件,如果它不存在,如果在目录中找到某个文件,则增加扩展名。但是,例如,如果存在一个扩展名为“1”的文件,一个扩展名为“3”,但 none 扩展名为“2”,则它应该写入下一个包含“4”的文件。所以应该在最高分机号上加1

到目前为止我的代码是:

    index = 0
    while os.path.exists('../FCR_Network_Coordinates_'+ str(index) + '.csv'):
        index+=1            
    with open('../FCR_Network_Coordinates_'+str(index)+'.csv', 'wb') as csv_file:
        writer = csv.writer(csv_file, delimiter=";")
        for key, value in sparse1.items():
            writer.writerow(['{:.1f}'.format(t) for t in key]+value)

编辑

它应该也适用于在路径名中添加参数的路径

 "../FCR_Network_Coordinates_"+"r_"+radius+"x_"+x+"y_"+y+"z_"‌​+z+"fcr_"+fcr_size+"‌​_"+new_number+".csv" 

可能看起来像:

FCR_Network_Coordinates_radius_3_x_0.3_y_0.3_z_2_fcr_2_1.csv

EDIT2

此外,如果文件名中有其他参数,则不应查看所有文件中数量最多的文件,而应查看具有这些参数的文件中数量最多的文件

即使存在文件“3”和“4”,您的代码也将停止搜索文件“2”(如果“2”不存在)

您需要使用 glob 来获取与您的模式匹配的所有文件

import glob
import re
files=glob.glob("../FCR_Network_Coordinates_*.csv")

接下来从您的文件名中删除所有非数字

file_nums=[]
for i, s in enumerate(files):

    num_str = re.search("(\d+).csv$",  files[i]) #capture only integer before ".csv" and EOL
    file_nums.append(parseInt(num_str.group(1)))  #convert to number

new_number=max(file_nums)+1 #find largest and increment

对文件列表进行排序以查找数量最多的文件。

像下面这样的东西应该适合你:

import glob
import os

# .....

existing_matches = glob.glob('../FCR_Network_Coordinates_*.csv')

if existing_matches:
    used_numbers = []
    for f in existing_matches:
        try:
            file_number = int(os.path.splitext(os.path.basename(f))[0].split('_')[-1])
            used_numbers.append(file_number)
        except ValueError:
            pass
    save_number = max(used_numbers) + 1
else:
    save_number = 1

with open('../FCR_Network_Coordinates_{}.csv'.format(save_number), 'wb') as csv_file:
    writer = csv.writer(csv_file, delimiter=";")
    for key, value in sparse1.items():
        writer.writerow(['{:.1f}'.format(t) for t in key] + value)

glob 查找名称与您的模式相似的所有文件,其中 * 用作通配符。

然后我们使用os.path来操作每个文件名并计算出名称中的数字是什么:

  • os.path.basename() 只得到文件名——例如'FCR_Network_Coordinates_1.csv'
  • os.path.splitext() 将文件名 ('FCR_Network_Coordinates_1') 与扩展名 ('.csv') 分开。取索引 0 处的元素得到文件名而不是扩展名
  • 根据 '_' 拆分它会在每次出现 '_' 时拆分它 - 导致 ['FCR', 'Network', 'Coordinates', '1'] 的列表。取索引 -1 得到这个列表中的最后一个条目,即 1.
  • 我们必须将其包装为 int() 才能对其应用数字运算。

如果某些文件名在下划线后使用字母而不是数字,我们也会发现错误。然后,我们取找到的数字的最大值并加一。如果没有找到数字,我们使用 1 作为文件名。

编辑: 为了响应问题更新,我们只需要更改我们的 glob 和我们写入的最终名称 - glob 更改为:

existing_matches = glob.glob('../FCR_Network_Coordinates_r_{}_x_{}_y_{}_z_{}_fcr_{}_*.csv'.format(
    radius, x, y, z, fcr_size))

文件开头行变为:

with open('../FCR_Network_Coordinates_r_{}_x_{}_y_{}_z_{}_fcr_{}_{}.csv'.format(
        radius, x, y, z, fcr_size, save_number), 'wb') as csv_file: