自动递增文件名
Autoincrement file names
这个问题来自[here]。我试着询问这是 link 提供的,但我被否决并被告知要问我自己的问题......所以我在这里。
我尝试为我自己的项目复制结果,但没有成功。当我尝试保存两个以上的文件时,脚本开始重命名每个文件,而不仅仅是我创建的新文件:
file_1_2_2_1_4_4_6_2_2.pdf
file1_3_2_3_3-6_5_1.pdf
file2_1_1_1-7_3_9.pdf
etc
而不是
file_1.pdf
file_2.pdf
file_3.pdf
etc.
有什么建议吗?
def save_file():
path = "/home/PycharmProjects/untitled/screening/"
newPath = "/home/PycharmProjects/untitled/screening/finished"
i = 1
for root, dirs, files in os.walk(path):
for name in files:
base, extension = os.path.splitext(name)
if not os.path.exists(os.path.join(newPath, base + extension)):
oldfile = os.path.join(os.path.abspath(root), name)
newfile = os.path.join(newPath, base + extension)
os.rename(oldfile, newfile)
else:
oldfile = os.path.join(os.path.abspath(root), name)
newfile = os.path.join(newPath, base + '_' + str(i) + extension)
i += 1
os.rename(oldfile, newfile)
预先感谢您的帮助!
出现此行为的原因是 os.walk
递归到子目录中。你的目标目录 IS 你的 sourcedir 的一个子目录 - 所以你将文件从 source 重命名为 target 及以后os.walk
进入 target 目录,并一直使用 "renaming" 策略将更多内容重命名为 itself,因为文件已经存在。
冗长的解决方案 - 其中大部分是创建文件结构,因此这是一个 Minimal, Complete, and Verifiable example 您可以使用的解决方案。
请参阅 os.walk
中 topdown=False
的文档
创建文件结构
import os
files = [ f"file_{i:05}x.txt" for i in range(20)]
org = os.path.abspath("./dir1/dir2/")
new = os.path.abspath("./dir1/dir2/new/")
os.makedirs(new)
# create all in org
for f in files:
with open(os.path.join(org,f),"w") as f:
f.write(" ")
#create every 4th one in new
for f in files[::4]:
with open(os.path.join(new,f),"w") as f:
f.write(" ")
for root,dirs,files in os.walk(org):
print(root)
print(" [d] ", dirs)
print(" [f] ", sorted(files))
输出:
/tmp/dir1/dir2
[d] ['new']
[f] ['file_00000x.txt', 'file_00001x.txt', 'file_00002x.txt', 'file_00003x.txt',
'file_00004x.txt', 'file_00005x.txt', 'file_00006x.txt', 'file_00007x.txt',
'file_00008x.txt', 'file_00009x.txt', 'file_00010x.txt', 'file_00011x.txt',
'file_00012x.txt', 'file_00013x.txt', 'file_00014x.txt', 'file_00015x.txt',
'file_00016x.txt', 'file_00017x.txt', 'file_00018x.txt', 'file_00019x.txt']
/tmp/dir1/dir2/new
[d] []
[f] ['file_00000x.txt', 'file_00004x.txt', 'file_00008x.txt', 'file_00012x.txt',
'file_00016x.txt']
固定方法
def save_file(old_path, new_path):
# topdown = False allows to modify the results to NOT recurse
for root, dirs, files in os.walk(old_path, topdown=False):
dirs = [] # do not recurse into subdirs ( whereto we copy the stuff )
root_abs = os.path.abspath(root)
new_abs = os.path.abspath(new_path)
for name in sorted(files): # sorting is convenience, not needed
old_file = os.path.join(root_abs, name)
new_file = os.path.join(new_abs, name)
# fix renaming logic (simplified) - looks until a unique name is found
i = 1
base, extension = os.path.splitext(name)
while os.path.exists(new_file):
# create a new name if it already exists
new_file = os.path.join(new_abs, f"{base}_{i}{extension}")
i += 1
# do the copy over
os.rename(old_file, new_file)
用法:
# uses the org/new from above
# org = os.path.abspath("./dir1/dir2/")
# new = os.path.abspath("./dir1/dir2/new/")
save_file(org,new)
for root,dirs,files in os.walk(org):
print(root)
print(" [d] ", dirs)
print(" [f] ", sorted(files))
之后输出:
/tmp/dir1/dir2
[d] ['new']
[f] []
/tmp/dir1/dir2/new
[d] []
[f] ['file_00000x.txt', 'file_00000x_1.txt', 'file_00001x.txt', 'file_00002x.txt',
'file_00003x.txt', 'file_00004x.txt', 'file_00004x_1.txt', 'file_00005x.txt',
'file_00006x.txt', 'file_00007x.txt', 'file_00008x.txt', 'file_00008x_1.txt',
'file_00009x.txt', 'file_00010x.txt', 'file_00011x.txt', 'file_00012x.txt',
'file_00012x_1.txt', 'file_00013x.txt', 'file_00014x.txt', 'file_00015x.txt',
'file_00016x.txt', 'file_00016x_1.txt', 'file_00017x.txt', 'file_00018x.txt',
'file_00019x.txt']
您看到 new
中的某些文件在其名称中获得了 _1
中缀,因为其中已经存在同名文件。
这个问题来自[here]。我试着询问这是 link 提供的,但我被否决并被告知要问我自己的问题......所以我在这里。
我尝试为我自己的项目复制结果,但没有成功。当我尝试保存两个以上的文件时,脚本开始重命名每个文件,而不仅仅是我创建的新文件:
file_1_2_2_1_4_4_6_2_2.pdf
file1_3_2_3_3-6_5_1.pdf
file2_1_1_1-7_3_9.pdf
etc
而不是
file_1.pdf
file_2.pdf
file_3.pdf
etc.
有什么建议吗?
def save_file():
path = "/home/PycharmProjects/untitled/screening/"
newPath = "/home/PycharmProjects/untitled/screening/finished"
i = 1
for root, dirs, files in os.walk(path):
for name in files:
base, extension = os.path.splitext(name)
if not os.path.exists(os.path.join(newPath, base + extension)):
oldfile = os.path.join(os.path.abspath(root), name)
newfile = os.path.join(newPath, base + extension)
os.rename(oldfile, newfile)
else:
oldfile = os.path.join(os.path.abspath(root), name)
newfile = os.path.join(newPath, base + '_' + str(i) + extension)
i += 1
os.rename(oldfile, newfile)
预先感谢您的帮助!
出现此行为的原因是 os.walk
递归到子目录中。你的目标目录 IS 你的 sourcedir 的一个子目录 - 所以你将文件从 source 重命名为 target 及以后os.walk
进入 target 目录,并一直使用 "renaming" 策略将更多内容重命名为 itself,因为文件已经存在。
冗长的解决方案 - 其中大部分是创建文件结构,因此这是一个 Minimal, Complete, and Verifiable example 您可以使用的解决方案。
请参阅 os.walk
中topdown=False
的文档
创建文件结构
import os
files = [ f"file_{i:05}x.txt" for i in range(20)]
org = os.path.abspath("./dir1/dir2/")
new = os.path.abspath("./dir1/dir2/new/")
os.makedirs(new)
# create all in org
for f in files:
with open(os.path.join(org,f),"w") as f:
f.write(" ")
#create every 4th one in new
for f in files[::4]:
with open(os.path.join(new,f),"w") as f:
f.write(" ")
for root,dirs,files in os.walk(org):
print(root)
print(" [d] ", dirs)
print(" [f] ", sorted(files))
输出:
/tmp/dir1/dir2
[d] ['new']
[f] ['file_00000x.txt', 'file_00001x.txt', 'file_00002x.txt', 'file_00003x.txt',
'file_00004x.txt', 'file_00005x.txt', 'file_00006x.txt', 'file_00007x.txt',
'file_00008x.txt', 'file_00009x.txt', 'file_00010x.txt', 'file_00011x.txt',
'file_00012x.txt', 'file_00013x.txt', 'file_00014x.txt', 'file_00015x.txt',
'file_00016x.txt', 'file_00017x.txt', 'file_00018x.txt', 'file_00019x.txt']
/tmp/dir1/dir2/new
[d] []
[f] ['file_00000x.txt', 'file_00004x.txt', 'file_00008x.txt', 'file_00012x.txt',
'file_00016x.txt']
固定方法
def save_file(old_path, new_path):
# topdown = False allows to modify the results to NOT recurse
for root, dirs, files in os.walk(old_path, topdown=False):
dirs = [] # do not recurse into subdirs ( whereto we copy the stuff )
root_abs = os.path.abspath(root)
new_abs = os.path.abspath(new_path)
for name in sorted(files): # sorting is convenience, not needed
old_file = os.path.join(root_abs, name)
new_file = os.path.join(new_abs, name)
# fix renaming logic (simplified) - looks until a unique name is found
i = 1
base, extension = os.path.splitext(name)
while os.path.exists(new_file):
# create a new name if it already exists
new_file = os.path.join(new_abs, f"{base}_{i}{extension}")
i += 1
# do the copy over
os.rename(old_file, new_file)
用法:
# uses the org/new from above
# org = os.path.abspath("./dir1/dir2/")
# new = os.path.abspath("./dir1/dir2/new/")
save_file(org,new)
for root,dirs,files in os.walk(org):
print(root)
print(" [d] ", dirs)
print(" [f] ", sorted(files))
之后输出:
/tmp/dir1/dir2
[d] ['new']
[f] []
/tmp/dir1/dir2/new
[d] []
[f] ['file_00000x.txt', 'file_00000x_1.txt', 'file_00001x.txt', 'file_00002x.txt',
'file_00003x.txt', 'file_00004x.txt', 'file_00004x_1.txt', 'file_00005x.txt',
'file_00006x.txt', 'file_00007x.txt', 'file_00008x.txt', 'file_00008x_1.txt',
'file_00009x.txt', 'file_00010x.txt', 'file_00011x.txt', 'file_00012x.txt',
'file_00012x_1.txt', 'file_00013x.txt', 'file_00014x.txt', 'file_00015x.txt',
'file_00016x.txt', 'file_00016x_1.txt', 'file_00017x.txt', 'file_00018x.txt',
'file_00019x.txt']
您看到 new
中的某些文件在其名称中获得了 _1
中缀,因为其中已经存在同名文件。